{"record":{"id":"44f06b298408d5a0","repo":"containerd/containerd","slug":"authorization-server-did-not-include-a-token-in-th","errorCode":null,"errorMessage":"authorization server did not include a token in the response","messagePattern":"authorization server did not include a token in the response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/remotes/docker/auth/fetch.go","lineNumber":38,"sourceCode":"\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\tremoteserrors \"github.com/containerd/containerd/v2/core/remotes/errors\"\n\t\"github.com/containerd/containerd/v2/pkg/tracing\"\n\t\"github.com/containerd/containerd/v2/version\"\n\t\"github.com/containerd/log\"\n)\n\nvar (\n\t// ErrNoToken is returned if a request is successful but the body does not\n\t// contain an authorization token.\n\tErrNoToken = errors.New(\"authorization server did not include a token in the response\")\n)\n\n// GenerateTokenOptions generates options for fetching a token based on a challenge\nfunc GenerateTokenOptions(ctx context.Context, host, username, secret string, c Challenge) (TokenOptions, error) {\n\trealm, ok := c.Parameters[\"realm\"]\n\tif !ok {\n\t\treturn TokenOptions{}, errors.New(\"no realm specified for token auth challenge\")\n\t}\n\n\trealmURL, err := url.Parse(realm)\n\tif err != nil {\n\t\treturn TokenOptions{}, fmt.Errorf(\"invalid token auth challenge realm: %w\", err)\n\t}\n\n\tto := TokenOptions{\n\t\tRealm:    realmURL.String(),\n\t\tService:  c.Parameters[\"service\"],\n\t\tUsername: username,","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/core/remotes/docker/auth/fetch.go#L20-L56","documentation":"ErrNoToken is returned when a registry's token endpoint answered HTTP 200 but the JSON body contains no token/access_token field, so the client has no bearer token to authenticate subsequent requests.","triggerScenarios":"Calling FetchToken or FetchTokenWithOAuth against a registry whose token server responds successfully but omits 'token'/'access_token' in the JSON body (e.g. misconfigured token service, error-in-200 responses, non-standard auth servers like some Artifactory/Quay setups).","commonSituations":"Misconfigured proxy or auth middleware stripping fields; registry returning an HTML/empty body with 200; OAuth device/refresh flows where the server only returns refresh tokens without access_token.","solutions":["Inspect the raw token endpoint response (curl the realm URL with the same params) and fix the auth server so it returns a token/access_token field","Check the realm in the WWW-Authenticate challenge points at the correct token service","Update containerd — newer versions accept access_token as well as token fields","If a proxy is in the path, verify it isn't mangling or truncating the response body"],"exampleFix":"// before: server returns {\"expires_in\":3600} with no token\n// after (server side) ensure response includes token\n{\"token\":\"eyJhbGciOi...\",\"expires_in\":3600}","handlingStrategy":"try-catch","validationCode":"// probe the token endpoint before pulling\nresp, _ := http.Get(tokenRealmURL)\nvar body map[string]any\njson.NewDecoder(resp.Body).Decode(&body)\nif body[\"token\"] == nil && body[\"access_token\"] == nil {\n    return errors.New(\"token server returns no token field\")\n}","typeGuard":null,"tryCatchPattern":"_, err := auth.FetchToken(ctx, client, to, opts)\nif errors.Is(err, auth.ErrNoToken) {\n    return fmt.Errorf(\"registry auth server misconfigured (no token in 200 body): %w\", err)\n}","preventionTips":["Curl the realm URL to verify the token service returns token/access_token","Audit proxies/CDNs for response rewriting","Keep containerd updated for broader token-field compatibility"],"tags":["containerd","registry","auth","token","network"],"backgroundTag":"registry-token-missing","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}