dagger/dagger · error

failed to base64-decode %s: %w

Error message

failed to base64-decode %s: %w

What it means

ClientMetadataFromHTTPHeaders returns this when the value of the ClientMetadataMetaKey header is not valid standard base64. The client encodes its JSON metadata as base64 in a header; a malformed or missing encoding cannot be decoded.

Source

Thrown at engine/opts.go:217

type clientMetadataCtxKey struct{}

func ContextWithClientMetadata(ctx context.Context, clientMetadata *ClientMetadata) context.Context {
	return context.WithValue(ctx, clientMetadataCtxKey{}, clientMetadata)
}

func ClientMetadataFromContext(ctx context.Context) (*ClientMetadata, error) {
	md, ok := ctx.Value(clientMetadataCtxKey{}).(*ClientMetadata)
	if !ok {
		return nil, fmt.Errorf("failed to get client metadata from context")
	}

	return md, nil
}

func ClientMetadataFromHTTPHeaders(h http.Header) (*ClientMetadata, error) {
	bs, err := base64.StdEncoding.DecodeString(h.Get(ClientMetadataMetaKey))
	if err != nil {
		return nil, fmt.Errorf("failed to base64-decode %s: %w", ClientMetadataMetaKey, err)
	}

	m := &ClientMetadata{}
	if err := json.Unmarshal(bs, m); err != nil {
		return nil, fmt.Errorf("failed to JSON-unmarshal %s: %w", ClientMetadataMetaKey, err)
	}

	if m.ClientVersion == "" {
		// fallback for old clients that don't send a client version!
		m.ClientVersion = m.Labels["dagger.io/client.version"]
	}
	if err := m.normalizeWorkspaceModuleLoading(); err != nil {
		return nil, err
	}

	return m, nil
}

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Ensure the client sets the header with base64.StdEncoding.EncodeToString(jsonBytes)
  2. Bypass or reconfigure proxies that rewrite/drop the metadata header
  3. Capture the outgoing request and inspect the header value for corruption or truncation
  4. Upgrade the dagger CLI so it uses the current header encoding

Example fix

// before
req.Header.Set(engine.ClientMetadataMetaKey, string(jsonBytes)) // raw JSON
// after
req.Header.Set(engine.ClientMetadataMetaKey, base64.StdEncoding.EncodeToString(jsonBytes))
Defensive patterns

Strategy: validation

Validate before calling

v := h.Get(engine.ClientMetadataMetaKey)
if v == "" {
    return fmt.Errorf("missing %s header", engine.ClientMetadataMetaKey)
}
if _, err := base64.StdEncoding.DecodeString(v); err != nil {
    return fmt.Errorf("malformed metadata header: %w", err)
}

Type guard

func validBase64(s string) bool {
    _, err := base64.StdEncoding.DecodeString(s)
    return err == nil
}

Try / catch

md, err := engine.ClientMetadataFromHTTPHeaders(h)
if err != nil {
    http.Error(w, "invalid client metadata header", http.StatusBadRequest)
    return
}

Prevention

When it happens

Trigger: ServeHTTP / nestedClientMetadataForRequest receive a request whose metadata header is not base64 (corrupted by a proxy, sent as raw JSON, or truncated).

Common situations: Reverse proxies or gateways mangling header values; custom clients writing raw JSON instead of base64; older tooling sending a legacy header format.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/010cee6ae05ac3f8. Report an issue: GitHub.