Hive RouterConfiguration

error_masking

The error_masking configuration controls how errors originating from your subgraphs are rewritten before they are returned to clients. It lets you redact error messages and strip sensitive extensions fields, globally or per subgraph.

For conceptual guidance and rollout strategy, see Error Masking.

Error masking only applies to subgraph errors — any error carrying an extensions.service field, whether it was returned by the subgraph or synthesized by the router for a network/HTTP failure. Errors produced by the router itself (for example GRAPHQL_PARSE_FAILED) are never masked.

Configuration Structure

router.config.yaml
error_masking:
  redacted_error_message: "Unexpected error" # message used when a subgraph error is masked
  all:
    error_message: true # mask the error message for every subgraph
    extensions: # optional — omit to leave extensions untouched
      mode: allow # allow | deny
      keys:
        - code
  subgraphs: # optional per-subgraph overrides
    products:
      error_message: false
      extensions:
        mode: deny
        keys: []

Error masking is enabled by default. Even with no error_masking block, subgraph error messages are replaced with "Unexpected error".

Options

redacted_error_message

  • Type: string
  • Default: "Unexpected error"

The message that replaces a subgraph error's original message whenever masking is applied.

all

  • Type: object
  • Default: { error_message: true }

The default masking rules applied to every subgraph. Individual subgraphs can override these under subgraphs.

all.error_message

  • Type: boolean
  • Default: true

Whether to replace the error message with redacted_error_message. Set to false to pass the original subgraph message through to clients.

This can also be forced off with the DISABLE_SUBGRAPH_ERROR_MASKING environment variable.

all.extensions

  • Type: object
  • Default: unset (extensions are not masked)

Controls which keys of the error extensions object are kept or removed. When omitted, the router leaves extensions untouched — only the message is masked.

Masking the message alone does not redact extensions. Sensitive detail is often carried in extensions (stack hints, internal codes, upstream HTTP bodies), so configure extensions explicitly when the default message-only masking is not enough.

all.extensions.mode
  • Type: string

  • Allowed values: allow, deny

  • Required: yes (when extensions is set)

  • allow: an allowlist — only the keys in keys are kept, everything else is removed. keys: [] removes all extensions.

  • deny: a denylist — only the keys in keys are removed, everything else is kept. keys: [] removes nothing.

all.extensions.keys
  • Type: string[]
  • Required: yes (when extensions is set)

The list of extensions keys the mode operates on. Only root-level keys are supported.

The router's well-known extension keys are:

KeyDescription
codeThe error code (for example SUBREQUEST_HTTP_ERROR).
serviceThe subgraph the error originated from.
affectedPathThe response path affected by the error.

Any other key a subgraph puts under extensions (for example http) is matched by its exact name.

subgraphs

  • Type: object (map of subgraph name → config)
  • Default: unset

Per-subgraph overrides. A subgraph listed here overrides the matching field from all.

subgraphs.<name>.error_message

Overrides message masking for this subgraph only. When omitted, the value from all is used.

subgraphs.<name>.extensions

  • Type: object
  • Default: unset

Overrides extensions masking for this subgraph only, using the same mode/keys shape as all.extensions. When omitted, the subgraph inherits all.extensions.

Each field is inherited independently. A subgraph that sets only error_message still uses all.extensions, and vice versa — you only override the fields you specify.

Disabling via environment variable

Setting DISABLE_SUBGRAPH_ERROR_MASKING=true forces all.error_message to false, overriding the config file. It is a convenient escape hatch for local debugging.

NameAccepted ValuesOverrides (YAML)
DISABLE_SUBGRAPH_ERROR_MASKINGtrue / falseerror_masking.all.error_message

This variable only affects message masking (all.error_message). It does not touch extensions masking or any per-subgraph override.

Behavior

  • Masking is the last step of the response pipeline, applied after metrics, tracing, and logging. Your observability tools always see the original, unmasked error — only the client-facing response is redacted.
  • Only errors with an extensions.service field are considered subgraph errors and are eligible for masking. This includes both errors returned by the subgraph and errors the router synthesizes for network/HTTP failures (SUBREQUEST_HTTP_ERROR, DOWNSTREAM_SERVICE_ERROR).
  • Message masking and extensions masking are independent: you can redact the message while keeping some extensions, or keep the message while stripping extensions.

Examples

Fully disable masking

router.config.yaml
error_masking:
  all:
    error_message: false

Custom redaction message

router.config.yaml
error_masking:
  redacted_error_message: "Something went wrong"

Mask the message and strip all extensions

router.config.yaml
error_masking:
  all:
    error_message: true
    extensions:
      mode: allow
      keys: [] # allow none — remove every extension

Keep only the error code

router.config.yaml
error_masking:
  all:
    error_message: true
    extensions:
      mode: allow
      keys:
        - code

Remove specific sensitive keys

router.config.yaml
error_masking:
  all:
    error_message: true
    extensions:
      mode: deny
      keys:
        - code
        - service

Per-subgraph override

Mask everything globally, but trust the internal products subgraph enough to pass its original messages and extensions through unmasked:

router.config.yaml
error_masking:
  all:
    error_message: true
    extensions:
      mode: allow
      keys: [] # allow none
  subgraphs:
    products:
      error_message: false
      extensions:
        mode: deny
        keys: [] # deny none — keep every extension