gastownhall/beads · error

az:// URL must include a storage account hostname

Error message

az:// URL must include a storage account hostname

What it means

az:// URLs must carry an Azure storage account hostname of the form account.blob.core.windows.net (az://account.blob.core.windows.net/container/path). An empty host means no storage account was specified.

Source

Thrown at internal/remotecache/url.go:162

			return fmt.Errorf("dolthub:// URL must have org/repo format (e.g., dolthub://myorg/myrepo)")
		}
	case "https", "http", "git+https", "git+http":
		if parsed.Host == "" {
			return fmt.Errorf("%s:// URL must include a hostname", scheme)
		}
	case "ssh", "git", "git+ssh":
		if parsed.Host == "" {
			return fmt.Errorf("%s:// URL must include a hostname", scheme)
		}
	case "s3", "aws", "gs":
		// s3://bucket/path, aws://bucket/path, gs://bucket/path — host is the bucket
		if parsed.Host == "" {
			return fmt.Errorf("%s:// URL must include a bucket name", scheme)
		}
	case "az":
		// az://account.blob.core.windows.net/container/path
		if parsed.Host == "" {
			return fmt.Errorf("az:// URL must include a storage account hostname")
		}
	case "oci":
		if parsed.Host == "" {
			return fmt.Errorf("oci:// URL must include a namespace or bucket host")
		}
	case "file":
		// file:// is allowed with any path
	case "git+file":
		// git+file:// is Dolt's normalized form for local git remotes.
	}

	return nil
}

// validateSCPURL validates an SCP-style URL (user@host:path)
func validateSCPURL(rawURL string) error {
	// Already matched gitSSHPattern, so structure is valid.
	// Extract host and verify no control chars (already checked above).

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use the full account hostname: "az://myaccount.blob.core.windows.net/container/path"
  2. Verify AZURE_STORAGE_ACCOUNT substitution produced the account.blob.core.windows.net host
  3. Include the container name after the host

Example fix

// before
remote := "az:///mycontainer/db"
// after
remote := "az://myaccount.blob.core.windows.net/mycontainer/db"
Defensive patterns

Strategy: validation

Validate before calling

func validAzureURL(u string) bool {
	rest, ok := strings.CutPrefix(u, "az://")
	if !ok { return false }
	host := rest
	if i := strings.Index(rest, "/"); i >= 0 { host = rest[:i] }
	return strings.Contains(host, ".blob.core.windows.net")
}

Type guard

func azureBlobURL(s string) (account string, ok bool) {
	rest, has := strings.CutPrefix(s, "az://")
	if !has { return "", false }
	if i := strings.Index(rest, "/"); i >= 0 { rest = rest[:i] }
	acct, suffix, found := strings.Cut(rest, ".")
	return acct, found && strings.HasSuffix(suffix, "blob.core.windows.net")
}

Try / catch

if err := remotecache.ValidateRemoteURL(u); err != nil {
	if strings.Contains(err.Error(), "storage account hostname") {
		return fmt.Errorf("azure remote %q must be az://account.blob.core.windows.net/container/path", u)
	}
}

Prevention

When it happens

Trigger: ValidateRemoteURL with "az://", "az:///container/path", or a URL where the account hostname was dropped.

Common situations: Copying only the container/path portion from an Azure portal URL, or empty ACCOUNT_NAME substitution in config.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/bcf6e3c1c94be591. Report an issue: GitHub.