ory/kratos · error

could not decode schema file

Error message

could not decode schema file: %w

What it means

ReadSchema supports base64:// URIs whose payload is base64-encoded schema JSON. If base64.StdEncoding.DecodeString fails (invalid characters, wrong padding), the error is wrapped as "could not decode schema file".

Solutions

  1. Re-encode the schema with standard base64 (echo -n '...' | base64) and no line wrapping
  2. Strip any whitespace/newlines from the base64 payload
  3. Remove a 'data:application/json;base64,' prefix if present — keep only base64:// + payload
  4. Convert URL-safe base64 (-, _) to standard (+, /) and restore padding
  5. Alternatively switch to a file:// or http(s):// schema URI

Example fix

// before
schema: "base64://e30j"
// after
schema: "base64://e30="
Defensive patterns

Strategy: validation

Validate before calling

// Go: preflight a base64:// schema URI
func base64SchemaDecodable(raw string) error {
	if !strings.HasPrefix(raw, "base64://") {
		return nil
	}
	payload := strings.TrimPrefix(raw, "base64://")
	data, err := base64.StdEncoding.DecodeString(payload)
	if err != nil {
		return fmt.Errorf("schema payload is not standard base64: %w", err)
	}
	return json.Unmarshal(data, &map[string]interface{}{})
}

Type guard

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

Try / catch

schema, err := h.ReadSchema(ctx, uri)
if err != nil {
	if base64.CorruptInputError(0) != nil && strings.Contains(err.Error(), "could not decode") {
		return fmt.Errorf("re-encode schema with `base64` (standard, no wrapping): %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Schema URI starting with base64:// whose remainder is not valid standard base64 — e.g. whitespace/newlines inside, URL-safe base64 (- and _) instead of standard, missing padding, or truncated data.

Common situations: Encoding with RawURLEncoding or URL-safe base64 then pasting into config; copy-paste introducing line breaks; hand-editing the base64 blob; using base64 output that includes the 'data:...;base64,' prefix.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07). Data as JSON: /api/errors/da9c5790a8813668. Report an issue: GitHub.

Appendix: source

Thrown at schema/handler.go:241

	x.PaginationHeader(w, *r.URL, int64(total), page, itemsPerPage)
	h.r.Writer().Write(w, r, ss)
}

func (h *Handler) ReadSchema(ctx context.Context, uri *url.URL) (data []byte, err error) {
	ctx, span := h.r.Tracer(ctx).Tracer().Start(ctx, "schema.Handler.ReadSchema")
	defer otelx.End(span, &err)

	switch uri.Scheme {
	case "file":
		data, err = os.ReadFile(uri.Host + uri.Path) //nolint:gosec
		if err != nil {
			return nil, errors.WithStack(fmt.Errorf("could not read schema file: %w", err))
		}
	case "base64":
		data, err = base64.StdEncoding.DecodeString(strings.TrimPrefix(uri.String(), "base64://"))
		if err != nil {
			return nil, errors.WithStack(fmt.Errorf("could not decode schema file: %w", err))
		}
	default:
		req, err := retryablehttp.NewRequestWithContext(ctx, http.MethodGet, uri.String(), nil)
		if err != nil {
			return nil, errors.WithStack(fmt.Errorf("could not create request: %w", err))
		}
		resp, err := h.r.HTTPClient(ctx).Do(req)
		if err != nil {
			return nil, errors.WithStack(herodot.ErrUpstreamError().WithReason("could not fetch schema").WithError(err.Error()).WithDetail("uri", uri))
		}
		defer func() { _ = resp.Body.Close() }()
		if resp.StatusCode != http.StatusOK {
			if resp.StatusCode == http.StatusNotFound {
				return nil, herodot.ErrNotFound().WithDetail("url", uri)
			}
			return nil, errors.WithStack(herodot.ErrUpstreamError().WithError("upstream error").WithDetail("status_code", resp.StatusCode).WithDetail("uri", uri))
		}
		data, err = io.ReadAll(io.LimitReader(resp.Body, maxSchemaSize))

View on GitHub (pinned to b86338da04)