{"id":"7a34d513359bd063","repo":"jackc/pgx","slug":"oauth-authentication-required-but-no-token-provide","errorCode":null,"errorMessage":"OAuth authentication required but no token provider configured","messagePattern":"OAuth authentication required but no token provider configured","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pgconn/auth_oauth.go","lineNumber":14,"sourceCode":"package pgconn\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/jackc/pgx/v5/pgproto3\"\n)\n\nfunc (c *PgConn) oauthAuth(ctx context.Context) error {\n\tif c.config.OAuthTokenProvider == nil {\n\t\treturn errors.New(\"OAuth authentication required but no token provider configured\")\n\t}\n\n\ttoken, err := c.config.OAuthTokenProvider(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to obtain OAuth token: %w\", err)\n\t}\n\n\t// https://www.rfc-editor.org/rfc/rfc7628.html#section-3.1\n\tinitialResponse := []byte(\"n,,\\x01auth=Bearer \" + token + \"\\x01\\x01\")\n\n\tsaslInitialResponse := &pgproto3.SASLInitialResponse{\n\t\tAuthMechanism: \"OAUTHBEARER\",\n\t\tData:          initialResponse,\n\t}\n\tc.frontend.Send(saslInitialResponse)\n\terr = c.flushWithPotentialWriteReadDeadlock()\n\tif err != nil {\n\t\treturn err","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/pgconn/auth_oauth.go#L1-L32","documentation":"Returned by (*PgConn).oauthAuth when the server demands OAUTHBEARER SASL authentication (RFC 7628) but Config.OAuthTokenProvider is nil. pgx will not invent a token; the caller must supply a function returning a bearer token. Without it the SASL initial response cannot be constructed.","triggerScenarios":"Connecting to a server whose AuthenticationSASL message advertises 'OAUTHBEARER' while Config.OAuthTokenProvider == nil. Triggered via pgconn.ConnectConfig / pgx.Connect / pgxpool.New when the server is configured for OAuth (e.g. Postgres with an OAuth extension or a managed cloud proxy).","commonSituations":"Cloud DB offerings that require OAuth/Azure AD tokens; forgetting to wire OAuthTokenProvider after switching from password auth; token provider closure capturing an expired/empty cache.","solutions":["Set Config.OAuthTokenProvider (or the pgxpool equivalent) to a function returning a valid bearer token before calling Connect.","Confirm the server actually requires OAuth; if it should accept password/SCRAM, check the server's pg_hba.conf or cloud auth settings.","Ensure the token provider refreshes tokens and returns errors (not panics) when the token source is unavailable."],"exampleFix":"// before\nconn, err := pgx.Connect(ctx, \"host=db user=app\")\n\n// after\nconn, err := pgx.ConnectConfig(ctx, &pgx.ConnConfig{\n    Host: \"db\",\n    User: \"app\",\n    OAuthTokenProvider: func(ctx context.Context) (string, error) {\n        return tokenCache.Get(ctx) // returns fresh bearer token\n    },\n})","handlingStrategy":"validation","validationCode":"// Before connecting, ensure a token provider is set when the server requires OAuth.\nfunc validateOAuthConfig(cc *pgx.ConnConfig) error {\n    // If you know the server uses OAUTHBEARER, the provider must be non-nil.\n    if requiresOAuth(cc) && cc.OAuthTokenProvider == nil {\n        return errors.New(\"server requires OAuth but OAuthTokenProvider is not set\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"conn, err := pgx.ConnectConfig(ctx, cc)\nif err != nil {\n    if strings.Contains(err.Error(), \"OAuth authentication required\") {\n        return fmt.Errorf(\"missing OAuth token provider: configure OAuthTokenProvider and retry: %w\", err)\n    }\n    return err\n}","preventionTips":["Centralize ConnConfig construction so OAuthTokenProvider is always wired for OAuth backends.","Make the token provider refresh tokens internally and surface errors cleanly.","Document which environments/hosts require OAuth in your service config."],"tags":["authentication","oauth","config","security"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}