{"record":{"id":"9cd8bf74224bae9f","repo":"kopia/kopia","slug":"unable-to-open-storage-connection","errorCode":null,"errorMessage":"unable to open storage connection","messagePattern":"unable to open storage connection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/providervalidation/providervalidation.go","lineNumber":90,"sourceCode":"\treturn errors.Wrap(err, \"error closing additional connections\")\n}\n\n// openEquivalentStorageConnections creates n-1 additional connections to the same underlying storage\n// and returns a slice of all connections.\nfunc openEquivalentStorageConnections(ctx context.Context, st blob.Storage, n int) (equivalentBlobStorageConnections, error) {\n\tresult := equivalentBlobStorageConnections{st}\n\tci := st.ConnectionInfo()\n\n\tlog(ctx).Infof(\"Opening %v equivalent storage connections...\", n-1)\n\n\tfor i := 1; i < n; i++ {\n\t\tc, err := blob.NewStorage(ctx, ci, false)\n\t\tif err != nil {\n\t\t\tif cerr := result.closeAdditional(ctx); cerr != nil {\n\t\t\t\tlog(ctx).Warn(\"unable to close storage connection\", \"err\", cerr)\n\t\t\t}\n\n\t\t\treturn nil, errors.Wrap(err, \"unable to open storage connection\")\n\t\t}\n\n\t\tlog(ctx).Debugw(\"opened equivalent storage connection\", \"connectionID\", i)\n\n\t\tresult = append(result, loggingwrapper.NewWrapper(c, log(ctx), nil, fmt.Sprintf(\"[STORAGE-%v] \", i)))\n\t}\n\n\treturn result, nil\n}\n\n// ValidateProvider runs a series of tests against provided storage to validate that\n// it can be used with Kopia.\n//\n//nolint:mnd,funlen,gocyclo,cyclop\nfunc ValidateProvider(ctx context.Context, st0 blob.Storage, opt Options) error {\n\tif os.Getenv(\"KOPIA_SKIP_PROVIDER_VALIDATION\") != \"\" {\n\t\treturn nil\n\t}","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/internal/providervalidation/providervalidation.go#L72-L108","documentation":"kopia's provider validation failed to create one of the additional blob.Storage connections to the same backend. The underlying blob.NewStorage error is wrapped as 'unable to open storage connection', and kopia first attempts to close already-opened connections, logging any close failure as a warning.","triggerScenarios":"blob.NewStorage(ctx, ci, false) returns an error while opening connection i (1..n-1) in openEquivalentStorageConnections — invalid connection info, bad credentials, unreachable endpoint, or too many parallel connections for the provider.","commonSituations":"Azure/S3 credentials valid for the first connection but throttled afterwards; transient DNS/network failure; misbuilt connection info for the duplicate connections.","solutions":["Check the wrapped cause for the actual blob.NewStorage failure (auth, network, throttling).","Verify provider credentials and endpoint in the connection info.","Reduce opt.NumEquivalentStorageConnections if the provider throttles concurrent connections.","Re-run validation; also clear KOPIA_SKIP_PROVIDER_VALIDATION only when validation is intended to run."],"exampleFix":"// before\nopt := &providervalidation.Options{NumEquivalentStorageConnections: 10}\n// after\nopt := &providervalidation.Options{NumEquivalentStorageConnections: 2}","handlingStrategy":"retry","validationCode":"// validate connection info before opening duplicates\nif err := ci.Validate(); err != nil {\n    return fmt.Errorf(\"invalid connection info: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := providervalidation.ValidateProvider(ctx, st, opts)\nvar retryable = isNetworkErr(err)\nif retryable {\n    time.Sleep(backoff)\n    err = providervalidation.ValidateProvider(ctx, st, opts)\n}","preventionTips":["Verify blob provider credentials and endpoint before validation","Reduce NumEquivalentStorageConnections on throttling providers","Ensure network/DNS reachability of the blob endpoint from the host","Pre-flight the first connection before requesting duplicates"],"tags":["blob-storage","connection-open","provider-validation"],"backgroundTag":"connection-refused","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}