Config
Matcher syntax
AI agents: fetch https://docs.erpc.cloud/config/matcher.llms.txt for the complete machine-readable version of this page (full configuration schema, defaults, worked examples, and source links). Append `.llms.txt` to any docs URL for the same treatment.AIFor agents: /config/matcher.llms.txt

Matcher syntax

Write one pattern, use it everywhere. eRPC's single WildcardMatch engine handles globs (eth_*), boolean composition (eth_* & !eth_call), and hex numeric ranges (>=0x100 & <=0x200) identically across cache policies, failsafe rules, rate limits, method allow/ignore lists, CORS, aliasing, upstream selectors, and routing. There is nothing new to learn when you reach a new config section.

Quick taste

Illustrative — any method, any finality; exclude debug_ from rate limits:

projects[].networks[].failsafe[]
erpc.yaml
projects:  - id: main    networks:      - architecture: evm        evm: { chainId: 1 }        failsafe:          # glob + boolean: all eth_ methods except eth_call          - matchMethod: "eth_* & !eth_call"            retry:              maxAttempts: 3

Agent reference

Copy one of these prompts into your AI agent session (Claude Code, Cursor, …) — each one points the agent at this page's machine-readable reference so it can do the work correctly:

Prompt Example #1: configure failsafe rules for specific methods and finalities
I want to tune my eRPC failsafe config so different retry/hedge policies apply to
different methods and finality states — e.g. aggressive retry for finalized eth_getLogs,
light retry for realtime, and no hedge on tx-hash lookups. Work with my existing eRPC config.
Read the matcher syntax reference first:
https://docs.erpc.cloud/config/matcher.llms.txt
Prompt Example #2: build an upstream method whitelist
One of my upstreams is an archive node that should only handle eth_getLogs,
eth_getBlockByNumber, eth_getBlockByHash, eth_getTransactionByHash, and
eth_getTransactionReceipt — all other methods should fall to other upstreams. Configure
ignoreMethods and allowMethods correctly. Work with my existing eRPC config. Reference:
https://docs.erpc.cloud/config/matcher.llms.txt
Prompt Example #3: set up cache policies with hex-range and finality scoping
I want eRPC to cache eth_getLogs and block-lookup methods only for finalized and
unfinalized requests, using hex block-range patterns in params so only concrete block
numbers are cached (not "latest"). Work with my existing eRPC config. Reference:
https://docs.erpc.cloud/config/matcher.llms.txt
Prompt Example #4: debug why my matchMethod or matchFinality rule is not matching
My eRPC failsafe rule with matchMethod "eth_get*" and matchFinality [finalized] does
not seem to be picked up for some requests. Walk me through how network-scope vs
upstream-scope failsafe selection works (4-tier vs config-order), and check my eRPC config
for ordering mistakes or wrong finality values. Reference:
https://docs.erpc.cloud/config/matcher.llms.txt
Prompt Example #5: add per-method rate-limit rules without accidentally stacking them
I want to add a rate-limit budget rule that caps debug_* and trace_* at 30 RPS and
a separate rule that caps eth_getBlockReceipts at 100 RPS, but I don't want a wildcard
"*" rule to stack on top and double-count. Explain how GetRulesByMethod works and write
the correct rules for my eRPC config. Reference:
https://docs.erpc.cloud/config/matcher.llms.txt
Matcher syntax — full agent referenceExpand for every option, default, and edge case — or copy this entire section into your AI assistant.

How it works

Core engine (WildcardMatch). Every call tokenizes the pattern string into operators (|, &, !, (, )) and atom tokens, then builds a recursive function AST via Pratt-style recursive-descent parsing (parseOr → parseAnd → parseUnary → parsePrimary). The resulting func(string) bool closure is invoked immediately against the test value. There is no compiled- pattern cache — each call re-tokenizes and re-parses. This is lightweight for short patterns but re-tokenization cost is paid on every forwarded request for failsafe executor selection.

Glob atoms. Plain atoms (no operator prefix) are dispatched to the go-wildcard library: * matches any number of characters, ? matches exactly one. The <empty> literal is handled specially before the glob library — it matches only the empty string.

Boolean composition. Operator precedence, highest to lowest: NOT (!) > AND (&) > OR (|). Parentheses override. Both & and | are left-associative. Spaces are atom separators — "a | b" and "a|b" are identical. The characters |, &, !, (, ) cannot appear as literals in a pattern — there is no escape mechanism.

Hex numeric comparisons. When the runtime value starts with 0x, the engine tries numeric comparison operators (>=, <=, >, <, =) as pattern prefixes. Both sides are parsed as hex integers. If the value does not start with 0x (e.g., a decimal block number or a named tag like "latest"), numeric operators fall through to glob matching and will not compare as expected. Use 0x* to match hex-format values, and combine with named tags using | for full coverage.

MatchesSelector and upstream tag awareness. The use-upstream directive and served-tip partition grouping use MatchesSelector rather than plain WildcardMatch. The function first tests the pattern against the upstream's id. If that matches, it returns true immediately. If the pattern contains no ! anywhere (purely-positive), it also iterates the upstream's tags []string and returns true on any tag match. Any ! anywhere in the pattern — even "!other-upstream" — disables tag matching entirely. This is intentional: a tag match must never rescue an upstream the operator meant to exclude.

matchMethodPattern helper. Inside SelectExecutor, method matching uses a helper that treats both empty string and "*" as match-anything, and tries exact equality before calling WildcardMatch to reduce overhead on common exact-match patterns. Source: common/match.go:L83-92

SelectExecutor — 4-tier priority for failsafe dispatch. Given executors with (matchMethod, matchFinality) fields and the request's (method, finality), SelectExecutor selects the first matching executor across four tiers in priority order (single pass):

  1. Exact — specific method AND specific finality
  2. Method-only — specific method, any finality (matchFinality: [])
  3. Finality-only — matchMethod: "*", specific finality
  4. Catch-all — matchMethod: "*", matchFinality: []

Important: upstream-level and network-level failsafe selection use different algorithms. Upstreams use the 4-tier priority algorithm above. Networks use a simpler first-match-in- config-order scan — if an any-method entry appears before a specific-method entry in config, the any-method entry wins. Place most-specific entries before catch-all entries in network-scope failsafe.

Cache policy param matching. matchParams is positional: index i in the config pattern matches params[i] in the request. Matching is recursive: map patterns require all keys to match, array patterns require equal length then per-element matching, string patterns use WildcardMatch, and other types are converted to strings via paramToString (JSON float64 numbers become their decimal string form: 1234.0 → "1234").

Auth method filter semantics. ignoreMethods is checked first (any match → method blocked), then allowMethods overrides (any match → force-allowed). Same semantics at upstream, project, and auth-strategy scopes.

Rate-limit rules. GetRulesByMethod returns all rules whose method pattern matches — not just the first. Multiple rules can simultaneously consume token-bucket permits for a single request.

Config schema

The matcher engine has no dedicated config block. The table below covers every config field matched via WildcardMatch, MatchesSelector, SelectExecutor, or MatchFinalities, grouped by subsystem.

Failsafe — *.failsafe[] (networks, upstreamDefaults, upstreams, networkDefaults, and cache connector failsafeForGets[]/failsafeForSets[])

FieldTypeDefaultBehavior / footguns
matchMethodstring"*" (set by SetDefaults when empty)WildcardMatch against the request's JSON-RPC method. Empty is rejected by Validate(). During defaults inheritance, a default's matchMethod is glob-matched against the entry's matchMethod to select which default to apply. Source: common/config.go:L1280, common/defaults.go:L2131-2137
matchFinality[]DataFinalityState[] (empty = any finality)Exact set-membership check at dispatch time: slices.Contains(list, finality). Empty list = catch-all finality tier. No wildcard inside the list — each element must be an exact finality name. Source: common/config.go:L1281, common/match.go:L38-41
matchCommitment[]string[] (empty = any commitment)Network scope only: first-match filter, AND-ed with method/finality/kind. Upstream-scope entries that set it fail startup. Values none|processed|confirmed|finalized, OR-ed, exact match (confirmed does not match processed). Compares the commitment erpc pins on the wire: the caller's value, else the svm.commitment default injection writes, else none. Non-SVM requests and SVM write methods (sendTransaction, simulateTransaction, requestAirdrop) are none. Source: common/config.go, architecture/svm/hooks.go, erpc/networks.go

Cache policies — database.evmJsonRpcCache.policies[]

FieldTypeDefaultBehavior / footguns
networkstring"*" (set by SetDefaults)WildcardMatch against the network ID (e.g., "evm:1", "evm:*"). Source: common/config.go:L320, data/cache_policy.go:L67
methodstring"*" (set by SetDefaults)WildcardMatch against the JSON-RPC method. Source: common/config.go:L321, data/cache_policy.go:L75
params[]interfacenil (nil = match any params)Positional param matching; strings use WildcardMatch. Maps/arrays matched recursively. Non-string types converted via paramToString. Source: common/config.go:L322, data/cache_policy.go:L166-232
finalityDataFinalityStatefinalized (zero value = 0)For MatchesForSet: exact equality. For MatchesForGet: finalized requests also match unfinalized policies; unknown finality matches any policy. Footgun: omitting finality yields a finalized-only policy silently. Source: common/config.go:L323, data/cache_policy.go:L99-150

Rate-limit rules — rateLimiters.budgets[].rules[]

FieldTypeDefaultBehavior / footguns
methodstringrequiredWildcardMatch against request method. ALL matching rules are returned (not just first) — each independently consumes a token-bucket permit. Source: common/config.go:L1811, upstream/ratelimiter_budget.go:L63-78

Upstream method filters — upstreams[], projects[], auth.strategies[]

FieldTypeDefaultBehavior / footguns
ignoreMethods[]stringnilWildcardMatch per entry; any match → method reported unsupported. Applied before allowMethods. Source: common/config.go:L731, upstream/upstream.go:L1375-1385
allowMethods[]stringnilWildcardMatch per entry; any match → overrides an ignoreMethods hit. To allow only eth_getLogs: set ignoreMethods: ["*"], allowMethods: ["eth_getLogs"]. Source: common/config.go:L732, upstream/upstream.go:L1388-1399

CORS, aliasing, headers, selectors

FieldTypeDefaultBehavior / footguns
projects[].cors.allowedOrigins[][]string["*"]WildcardMatch against Origin header; first match allows. Source: erpc/http_server.go:L1024
server.aliasing.rules[].matchDomainstring—WildcardMatch against Host header (port stripped); first rule match wins. Source: common/config.go:L258, erpc/http_server.go:L244-257
projects[].forwardHeaders[][]stringnilWildcardMatch against incoming header names; matching headers forwarded to upstreams. Source: common/config.go:L519, erpc/http_server.go:L480-493
upstreams[].idstring—Primary identity matched by MatchesSelector against use-upstream directive value. Source: common/matcher.go:L106-112
upstreams[].tags[][]stringnilSecondary match by MatchesSelector if id didn't match and pattern has no !. Source: common/matcher.go:L73-100

Score multipliers — upstreams[].routing.scoreMultipliers[]

FieldTypeDefaultBehavior / footguns
networkstring"" (empty = any)WildcardMatch against network ID. Source: common/config.go:L798
methodstring"" (empty = any)WildcardMatch against method. Source: common/config.go:L799
finality[]DataFinalityState[] (any)slices.Contains check. Source: common/config.go:L800

Tracing force-trace matchers — tracing.forceTraceMatchers[]

FieldTypeDefaultBehavior / footguns
networkstring"" (absent = any)WildcardMatch against network ID. Both network AND method must match. Source: common/config.go:L241, common/tracing_core.go:L306-329
methodstring"" (absent = any)WildcardMatch against method. Source: common/config.go:L245

Served-tip guaranteed methods — networks[].evm.servedTip.guaranteedMethods[]

FieldTypeDefaultBehavior / footguns
networks[].evm.servedTip.guaranteedMethods[][]string—Each element validated by ValidatePattern at config load (the only config field with startup validation). At runtime, WildcardMatch against the request method determines whether the served-tip mechanism applies. Source: common/validation.go:L1323-1326

Provider network overrides — providers[].overrides (map keys)

FieldTypeDefaultBehavior / footguns
providers[].overrides (map key)string—WildcardMatch pattern against network ID. First matching key wins. Source: thirdparty/provider.go:L80-L91 (opens in a new tab)

Consensus quota tags — consensus/quota.go

Tag membership for quota matching uses WildcardMatch(pattern, t) against each tag string in the upstream config's Tags slice. Source: consensus/quota.go:L96 (opens in a new tab)

Static responses — networks[].staticResponses[] (NOT WildcardMatch)

FieldTypeDefaultBehavior / footguns
methodstringrequiredExact string equality only — no glob, no boolean operators. "eth_getBlock*" will NOT match eth_getBlockByNumber. Source: common/static_response.go:L16
params[]interfacenil (nil = match any params)Deep equality with numeric-type tolerance (YAML int vs JSON float64). NOT WildcardMatch. Source: common/static_response.go:L19-39

DataFinalityState values

YAML stringGo constantiotaMeaning
"finalized"DataFinalityStateFinalized0Block ≤ upstream finalized block. Zero value — omitting finality in config gives this.
"unfinalized"DataFinalityStateUnfinalized1Block known and > upstream finalized block.
"realtime"DataFinalityStateRealtime2Fresh, block-unbound data (e.g., eth_gasPrice).
"unknown"DataFinalityStateUnknown3Block number cannot be determined (trace-by-hash, etc.).

YAML/JSON accepts string names or their numeric iota indices ("0" = finalized, "1" = unfinalized, "2" = realtime, "3" = unknown).

Source: common/data.go:L8-76

Worked examples

All patterns below are distilled from real production fleets; comments explain the non-obvious choices.

1. Method whitelist on a narrow upstream: block everything, allow only what it indexes. Production indexing upstreams (e.g. archive nodes, specialized caches) only serve a small set of methods — blocking everything else avoids wasting a request slot and lets the router immediately fall to a full-service upstream. This is the canonical ignoreMethods + allowMethods pattern used on every specialized upstream in the fleet:

upstreams[]
erpc.yaml
upstreams:  - id: archive-node    # Block all methods on this upstream by default    ignoreMethods:      - "*"    # Then re-allow only the methods this upstream actually serves — anything    # else immediately falls to the next upstream without a wasted RTT    allowMethods:      - "eth_getLogs"      - "eth_getBlockByNumber"      - "eth_getBlockByHash"      - "eth_getBlockReceipts"      - "eth_getTransactionByHash"      - "eth_getTransactionReceipt"

2. Finality-scoped network failsafe: different retry+hedge per finality state. In production, realtime and unfinalized requests are subject to block-availability races — a short non-zero delay gives the state-propagation poller time to catch up before retrying. Finalized requests have no race, so delay: 0 is correct there. At upstream scope the 4-tier priority resolves conflicts automatically; at network scope, most-specific entries MUST come first in config order:

projects[].networks[].failsafe[]
erpc.yaml
failsafe:  # Specific method + specific finality wins over all catch-alls (at upstream scope,  # this is tier 1 priority; at network scope, place this BEFORE the catch-all)  - matchMethod: "eth_call|eth_getLogs"    matchFinality: [realtime, unfinalized]    retry:      maxAttempts: 4      # MUST NOT be 0: a short delay lets block-state propagation catch up before      # retrying a "block not available yet" error across another upstream      delay: 50ms    hedge:      delay:        quantile: 0.95        min: 500ms        max: 10s      maxCount: 1  # Same methods, finalized — no block-availability race, so delay: 0 is correct  - matchMethod: "eth_call|eth_getLogs"    matchFinality: [finalized, unknown]    retry:      maxAttempts: 4      delay: 0  # Catch-all for everything else — realtime/unfinalized needs the delay too  - matchMethod: "*"    matchFinality: [realtime, unfinalized]    retry:      maxAttempts: 6      delay: 50ms  - matchMethod: "*"    matchFinality: [finalized, unknown]    retry:      maxAttempts: 6      delay: 0

3. Per-method upstream timeouts using glob priority. Production upstream failsafe sets tight timeouts per method tier — heavy methods like eth_getLogs need a generous ceiling; light point-reads need a tight one to encourage fast hedging on stuck upstreams. Glob patterns (eth_get*) serve as a catch-all tier, with more-specific exact entries placed before them. At upstream scope, 4-tier priority handles the ordering automatically, so explicit placement is not required — but it is still good style:

upstreamDefaults.failsafe[]
erpc.yaml
upstreamDefaults:  failsafe:    # Exact method entries are tier 2 (method-only) — win over the glob catch-all tier    - matchMethod: "eth_getLogs|eth_getBlockReceipts"      timeout:        # Variable latency tied to range/density — routinely seconds on big queries        duration: 15s    - matchMethod: "eth_getTransactionReceipt"      timeout:        duration: 8s    - matchMethod: "eth_getBlockByNumber"      timeout:        # min raised: archive lookups on fast chains (Sei, Monad) can take 350–500ms        duration: 3s    - matchMethod: "trace_*|debug_*|arbtrace_*"      timeout:        # Trace methods can be slow — 30s gives them room without blocking others        duration: 30s    # Glob catch-all for remaining eth_get* light getters — tier 2, wins over "*"    - matchMethod: "eth_get*"      timeout:        duration: 5s    # Final catch-all — tier 4, lowest priority    - matchMethod: "*"      timeout:        duration: 60s

4. Cache policy with explicit method allowlist and all-finality coverage. In production, cache policies use a pipe-joined method pattern (|) rather than a broad glob because eth_get* would flood every connector with requests for methods nothing serves (eth_getBalance, eth_getCode, eth_getStorageAt, …), paying a connector RTT for a guaranteed miss. Three finality tiers cover all concrete-block requests; realtime finality is intentionally excluded so head-tracking queries always hit fresh upstreams:

database:
  evmJsonRpcCache:
    policies:
      # Using | instead of eth_get* avoids cache misses on balance/code/storage methods
      - network: "evm:1"
        method: "eth_getBlockByNumber|eth_getBlockByHash|eth_getBlockReceipts|eth_getLogs|eth_getTransactionByHash|eth_getTransactionReceipt"
        finality: unfinalized
        connector: my-cache
      - network: "evm:1"
        method: "eth_getBlockByNumber|eth_getBlockByHash|eth_getBlockReceipts|eth_getLogs|eth_getTransactionByHash|eth_getTransactionReceipt"
        finality: unknown
        connector: my-cache
      - network: "evm:1"
        method: "eth_getBlockByNumber|eth_getBlockByHash|eth_getBlockReceipts|eth_getLogs|eth_getTransactionByHash|eth_getTransactionReceipt"
        finality: finalized
        connector: my-cache
      # realtime deliberately omitted — eth_blockNumber / eth_getBlockByNumber("latest")
      # must always hit upstreams so clients see the current chain head

5. Per-method rate-limit rules: protect heavy methods without stacking a wildcard. Heavy-method traffic (eth_getBlockReceipts, trace_*) can exhaust proxy concurrency when a single user sends high-error-rate bursts, holding a connection per failed attempt. A method-specific rule caps only that traffic; a separate wildcard rule caps global volume. Note that ALL matching rules fire simultaneously — if you add a "*" rule AND a specific rule, a heavy-method request consumes from both buckets:

rateLimiters.budgets[]
erpc.yaml
rateLimiters:  budgets:    - id: chain-admission      rules:        # Heavy receipt methods empirically drive proxy-connection stack-ups — cap tightly.        # Healthy peak is ~5 RPS total; 100 RPS gives 20× headroom for legitimate spikes        - method: "eth_getBlockReceipts|eth_getTransactionReceipt"          maxCount: 100          period: 1s        # Trace methods have low typical volume; 30 RPS matches observed traffic        - method: "debug_*|trace_*|arbtrace_*"          maxCount: 30          period: 1s        # Global wildcard intentionally omitted here — these two rules are        # independent; a request matching both rules debits both buckets

Request/response behavior

  • The use-upstream directive is set via the X-ERPC-Use-Upstream request header or query param. The value is a MatchesSelector pattern — id first, then tags if no ! in pattern.
  • ignoreMethods and allowMethods at project or upstream scope cause eRPC to return ErrUpstreamMethodIgnored for blocked methods — surfaced to the client as an upstream unsupported error.
  • Rate-limit rules whose method matches fire simultaneously: a request denied by two matching rules gets a rate-limit error even if only one rule was intended as the effective gate.
  • A malformed pattern in most config fields silently skips matches at runtime (caller continue-on-error pattern) — no error is returned to the client; the config field is simply treated as non-matching.

Best practices

  • Prefer exact method names or simple globs ("eth_*", "*") on hot paths like failsafe matchMethod — complex boolean expressions re-parse on every request with no caching.
  • At network scope, order failsafe entries from most-specific to least-specific manually — unlike upstream scope, there is no 4-tier priority; the first matching entry wins.
  • For rate-limit budgets, remember that all matching rules fire simultaneously — a global "*" rule and a per-method rule both debit their buckets. Size them with overlap in mind.
  • Use ignoreMethods: ["*"] + allowMethods: [...] to build explicit whitelists — it is cleaner and safer than long lists of specific ignore patterns.
  • For hex numeric comparisons in cache policy params, always also cover named tags with |: "(latest | safe | finalized) | >=0x1000000" — a value like "latest" has no 0x prefix and falls through to glob matching, so numeric-only patterns miss it.
  • Avoid setting ! in use-upstream selector patterns unless you specifically want to suppress tag matching — any ! anywhere in the pattern disables tag fallback entirely.
  • Validate patterns at startup where possible: ValidatePattern is only automatically called for evm.servedTip.guaranteedMethods; other fields accept invalid patterns silently and fail at runtime.

Edge cases & gotchas

  1. No escaping for meta-characters. |, &, !, (, ) cannot appear as literal values in a pattern. A method name like net_!custom is untestable via WildcardMatch. Source: common/matcher.go:L226-258
  2. Spaces are atom separators. "eth_getLogs " (trailing space) tokenizes as ["eth_getLogs"]. A pattern intended to match a literal space will silently split into two tokens. Source: common/matcher.go:L229-260
  3. Numeric operators require 0x prefix on the runtime value. >100 against value "200" does NOT compare numerically — it falls through to glob. Use hex-prefixed values ("0x64" = 100) to enable numeric comparison. Source: common/matcher.go:L373-391
  4. Hex overflow at 0x7FFFFFFFFFFFFFFF. parseNumber uses strconv.ParseInt(s, 16, 64) — values above signed 64-bit max parse silently as errors and compareNumbers returns false. Source: common/matcher.go:L399-438
  5. MatchesSelector negation guard is coarse. Any ! anywhere in the pattern — even "!other-upstream" — disables tag matching entirely. This is by design: a tag match must not rescue an excluded upstream. Source: common/matcher.go:L87-89
  6. Network-level vs upstream-level failsafe selection differ. Upstream uses 4-tier priority; network uses config-order first-match. Same field names, different semantics. Source: upstream/upstream.go:L372-408, erpc/networks.go:L910-928
  7. matchFinality: [] is catch-all at dispatch, but MatchFinalities empty-means-any is only for defaults merging. Two different functions handle the same field in different contexts. Source: common/defaults.go:L17-34, common/match.go:L38-41
  8. Static response method is exact equality, not wildcard. Unlike every other string matcher, FindStaticResponseMatch uses byte equality. A glob pattern in staticResponses[].method is silently treated as a literal string. Source: common/static_response.go:L16
  9. CachePolicyConfig.finality zero-value is finalized. Omitting finality in a cache policy gives a finalized-only policy without any warning. Source: common/data.go:L15
  10. Multiple rate-limit rules fire simultaneously. All rules whose method pattern matches are returned and each independently debits a token bucket. A single request may be throttled by a "*" rule and a specific-method rule at the same time. Source: upstream/ratelimiter_budget.go:L63-78
  11. ValidatePattern is called only for evm.servedTip.guaranteedMethods at startup. Other pattern fields (cache policy method, failsafe matchMethod, etc.) are not validated at config load — an invalid pattern silently skips matches at runtime. Source: common/validation.go:L1323-1326
  12. WildcardMatch concurrent calls are safe (no shared mutable state per call) but RateLimiterBudget.GetRulesByMethod holds a sync.RWMutex during iteration. Re-tokenization cost is paid under the read lock on every matching call. Source: upstream/ratelimiter_budget.go:L63-78
  13. paramToString on float64 from JSON. JSON numbers decode as float64; strconv.FormatFloat(v, 'f', -1, 64) produces "1234" not "1234.0". A string pattern "123*" would match numeric param 1234. Source: data/cache_policy.go:L234-249
  14. Cache MatchesForGet returns true for unknown finality across all policies. A request with indeterminate finality can be served from a finalized policy's cache, potentially returning stale data. Source: data/cache_policy.go:L146-149
  15. Legacy single-object failsafe migration is silent. An old failsafe: {…} (object form) is quietly converted to a 1-element slice. No log or warning is emitted. The migration only forces matchMethod to "*" when the field is empty — an explicitly-set non-empty matchMethod value (e.g., "eth_call") is preserved as-is. The migration applies at YAML parse time across NetworkConfig, NetworkDefaults, and UpstreamConfig. Source: common/config.go:L2041-2103
  16. Zero-config auto-generated project only when projects: is entirely absent. Even projects: [] skips the auto-generated 'main' project defaults. Source: common/defaults.go:L100-167
  17. DataFinalityStateAll = -1 is an internal sentinel. It must never appear in config or on requests — it only lives in health-tracker cross-finality rollup keys. Source: common/data.go:L29-36
  18. Empty pattern in MatchesSelector always returns false. The function guards against empty patterns at entry and immediately returns false. Callers must ensure the use-upstream directive value is non-empty — an empty X-ERPC-Use-Upstream header or query param results in no upstream being selected by that directive. Source: common/matcher.go:L73

Observability

MetricTypeLabelsWhen it fires
erpc_unexpected_panic_total{scope="validate-pattern"}counterscope, extra (pattern), errorValidatePattern catches a tokenizer/parser panic
erpc_network_static_response_served_totalcounterproject, network, methodEvery static-response cache hit in tryServeStaticResponse

Trace span attributes set during network-level failsafe selection:

  • failsafe.matched_method — the matched matchMethod value
  • failsafe.matched_finalities — the matched finality list

Source: erpc/networks.go:L1179-1180

Notable log lines:

  • "method support result" — Debug, upstream/upstream.go, fields: allowed (bool), method (string). Emitted after each upstream method-support check.
  • "skipping static response: cannot inspect request" — Debug, erpc/networks_static_responses.go. Emitted when params cannot be read for static-response matching.
  • "served static response (no upstream contacted)" — Debug, erpc/networks_static_responses.go. Emitted on a static-response cache hit.
  • "error matching ignore method … with method …" — Error, auth/authorizer.go. Emitted when WildcardMatch returns an error during auth method-filter evaluation.

Source code entry points

Related pages

  • Failsafe — uses matchMethod + matchFinality for executor dispatch.
  • Rate limiters — uses method pattern; all matching rules fire simultaneously.
  • Auth — uses ignoreMethods/allowMethods with same ignore-then-allow semantics.
  • Database / cache — uses network, method, and params patterns in policies.
  • Projects — project-level ignoreMethods/allowMethods and forwardHeaders patterns.