{"record":{"id":"cdc31fd858a6538d","repo":"docker/cli","slug":"error-pinging-v2-registry-w","errorCode":null,"errorMessage":"error pinging v2 registry: %w","messagePattern":"error pinging v2 registry: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/registryclient/endpoint.go","lineNumber":85,"sourceCode":"// getHTTPTransport builds a transport for use in communicating with a registry\nfunc getHTTPTransport(authConfig registrytypes.AuthConfig, endpoint registry.APIEndpoint, repoName, userAgent string, actions []string) (http.RoundTripper, error) {\n\t// get the http transport, this will be used in a client to upload manifest\n\tbase := &http.Transport{\n\t\tProxy: http.ProxyFromEnvironment,\n\t\tDial: (&net.Dialer{\n\t\t\tTimeout:   30 * time.Second,\n\t\t\tKeepAlive: 30 * time.Second,\n\t\t}).Dial,\n\t\tTLSHandshakeTimeout: 10 * time.Second,\n\t\tTLSClientConfig:     endpoint.TLSConfig,\n\t\tDisableKeepAlives:   true,\n\t}\n\n\tmodifiers := registry.Headers(userAgent, http.Header{})\n\tauthTransport := transport.NewTransport(base, modifiers...)\n\tchallengeManager, err := registry.PingV2Registry(endpoint.URL, authTransport)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error pinging v2 registry: %w\", err)\n\t}\n\tif authConfig.RegistryToken != \"\" {\n\t\tpassThruTokenHandler := &existingTokenHandler{token: authConfig.RegistryToken}\n\t\tmodifiers = append(modifiers, auth.NewAuthorizer(challengeManager, passThruTokenHandler))\n\t} else {\n\t\tif len(actions) == 0 {\n\t\t\tactions = []string{\"pull\"}\n\t\t}\n\t\tcreds := &staticCredentialStore{authConfig: &authConfig}\n\t\ttokenHandler := auth.NewTokenHandler(authTransport, creds, repoName, actions...)\n\t\tbasicHandler := auth.NewBasicHandler(creds)\n\t\tmodifiers = append(modifiers, auth.NewAuthorizer(challengeManager, tokenHandler, basicHandler))\n\t}\n\treturn transport.NewTransport(base, modifiers...), nil\n}\n\ntype existingTokenHandler struct {\n\ttoken string","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/internal/registryclient/endpoint.go#L67-L103","documentation":"Root transport error from getHTTPTransport: registry.PingV2Registry GETs the /v2/ endpoint to learn the auth challenges, and any failure (connection refused, TLS error, non-2xx, non-v2 registry) is wrapped here. It is the concrete cause that 601 wraps, so most \"failed to configure transport\" reports trace back to this.","triggerScenarios":"The registry host is unreachable, the TLS certificate is invalid or self-signed (and insecure mode is off), the registry does not implement the distribution v2 API, or the /v2/ ping returns an error status before auth can proceed.","commonSituations":"Wrong registry URL; self-signed cert without insecure flag; registry behind a proxy that mangles /v2/; legacy v1-only registry; DNS failure; corporate firewall blocking the host.","solutions":["Run curl -v https://<host>/v2/ to see the exact HTTP/TLS failure.","If the cert is private/self-signed, enable insecure mode (insecure=true / --insecure-registry).","Confirm the registry software implements the OCI/Docker distribution v2 API.","Verify DNS resolution and reachability (port open, no firewall).","Re-authenticate with `docker login <host>` if the ping is failing on auth."],"exampleFix":"$ curl -v https://registry.example.com/v2/\n# if self-signed cert error, enable insecure mode:\ncli := registryclient.NewRegistryClient(resolver, ua, true)","handlingStrategy":"validation","validationCode":"// Manual v2 ping mirroring what the client does internally.\nfunc canPingV2(ctx context.Context, regURL string, insecure bool) error {\n    tr := &http.Transport{}\n    if insecure {\n        tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}\n    }\n    c := &http.Client{Transport: tr, Timeout: 10 * time.Second}\n    req, _ := http.NewRequestWithContext(ctx, \"GET\", regURL+\"/v2/\", nil)\n    resp, err := c.Do(req)\n    if err != nil {\n        return err\n    }\n    defer resp.Body.Close()\n    if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusUnauthorized {\n        return fmt.Errorf(\"unexpected v2 ping status %s\", resp.Status)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Differentiate retryable network errors from fatal TLS/config errors.\nif errors.Is(err, context.DeadlineExceeded) || isConnRefused(err) {\n    // retry with backoff\n} else if isTLSerr(err) {\n    // prompt user about insecure mode / CA bundle\n}","preventionTips":["Run a /v2/ preflight before operating on a registry.","Install the registry's CA into the trust store, or enable insecure mode deliberately.","Confirm the registry speaks distribution v2 (not a v1-only or plain HTTP server).","Keep credentials valid via docker login."],"tags":["docker","registry","network","tls","authentication"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}