vxcontrol/pentagi · error

could not create Google OpenID client

Error message

could not create Google OpenID client: %w

What it means

Inside newGoogleEmailResolver (backend/pkg/server/oauth/google.go:22), oidc.NewProvider fetches Google's OpenID Connect discovery document from https://accounts.google.com. If that HTTP discovery request fails, the error is wrapped as "could not create Google OpenID client" and the email resolver aborts before any token is inspected.

Solutions

  1. Restore outbound HTTPS connectivity to https://accounts.google.com from the backend (proxy/firewall/DNS).
  2. If a proxy is required, configure HTTPS_PROXY for the process.
  3. Cache the OIDC provider (create it once at startup) instead of per-request to reduce discovery calls and surface config issues early.
  4. Retry the login if the failure was transient.

Example fix

// before (per request)
provider, err := oidc.NewProvider(ctx, "https://accounts.google.com")

// after (once at startup)
var googleProvider *oidc.Provider
func initGoogleOIDC(ctx context.Context) error {
    p, err := oidc.NewProvider(ctx, "https://accounts.google.com")
    if err != nil {
        return err
    }
    googleProvider = p
    return nil
}
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight reachability of Google's OIDC discovery document
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://accounts.google.com/.well-known/openid-configuration", nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
    return fmt.Errorf("Google OIDC discovery unreachable (check egress/proxy/DNS): %w", err)
}
resp.Body.Close()

Try / catch

email, verified, err := googleEmailResolver(ctx, nonce, token)
if err != nil {
    var ue *url.Error
    if errors.As(err, &ue) || strings.Contains(err.Error(), "could not create Google OpenID client") {
        return "", false, fmt.Errorf("sign-in temporarily unavailable (cannot reach Google); retry")
    }
    return "", false, err
}

Prevention

When it happens

Trigger: Any callback-time invocation where oidc.NewProvider cannot reach or parse the discovery document: network/DNS failure, blocked egress, TLS interception, or Google returning a non-200/error response.

Common situations: Backend running in an air-gapped or firewalled environment without access to accounts.google.com; corporate proxy with TLS re-signing; Docker/Compose network without outbound internet; transient Google outage during login.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/8d615fcd19e72839. Report an issue: GitHub.

Appendix: source

Thrown at backend/pkg/server/oauth/google.go:22

	"context"
	"fmt"

	"github.com/coreos/go-oidc/v3/oidc"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
)

type googleTokenClaims struct {
	Nonce         string `json:"nonce"`
	Email         string `json:"email"`
	EmailVerified bool   `json:"email_verified"`
}

func newGoogleEmailResolver(clientID string) OAuthEmailResolver {
	return func(ctx context.Context, nonce string, token *oauth2.Token) (string, bool, error) {
		provider, err := oidc.NewProvider(ctx, "https://accounts.google.com")
		if err != nil {
			return "", false, fmt.Errorf("could not create Google OpenID client: %w", err)
		}

		oidToken, ok := token.Extra("id_token").(string)
		if !ok {
			return "", false, fmt.Errorf("id_token is not present in the token")
		}

		verifier := provider.Verifier(&oidc.Config{ClientID: clientID})
		idToken, err := verifier.Verify(ctx, oidToken)
		if err != nil {
			return "", false, fmt.Errorf("could not verify Google ID Token: %w", err)
		}

		if idToken.Nonce != nonce {
			return "", false, fmt.Errorf("nonce mismatch in Google ID Token")
		}

		if err = idToken.VerifyAccessToken(token.AccessToken); err != nil {

View on GitHub (pinned to ea665308ba)