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
- Re-encode the schema with standard base64 (echo -n '...' | base64) and no line wrapping
- Strip any whitespace/newlines from the base64 payload
- Remove a 'data:application/json;base64,' prefix if present — keep only base64:// + payload
- Convert URL-safe base64 (-, _) to standard (+, /) and restore padding
- 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
- Generate the payload with `base64 -w0` (no line wrapping)
- Never use URL-safe base64 for base64:// URIs
- Strip data-URI prefixes and whitespace before embedding
- Validate the decoded output is valid JSON before deploying
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
- could not read schema file
- could not create request
- no credentials found
- failed to unmarshal webhook configuration for
- failed to unmarshal notify_previous_addresses configuration…
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)