ErrLookup › Background articles › "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it
"Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it
Invalid config value errors — messages like "Invalid value '%{value}' for parameter", "allowed values are", "invalid bool value", "must be one of" — fire when a setting receives a value outside the fixed set, type, or range a library validates. Developers meet them at server boot (Puma, Hadoop), during bootstrap (Hibernate, Maven), on CLI runs and publishes (fluentd, deno publish), or at first use of a configured feature (Chroma, AFFiNE), most often from a typo, wrong case, stray whitespace, a wrong value type, or a value that was never valid in this version.
Distilled from 133 documented records across 41 repositories.
Background
Configuration reaches libraries as raw strings — XML property values, YAML, env vars, CLI flags — but internally the library wants an enum member, a positive integer, an object instance, or a member of a small allowlist. Nearly every library therefore puts a validation gate at the parse or configure boundary. Puppet settings run hook procs at config-parse time, Puma validates the IO selector backend while building its reactor at boot, Hibernate's ConfigurationHelper inspects setting types while assembling a SessionFactory or EntityManagerFactory, and fluentd validates parser type declarations during configure, before any data flows. This family is what that gate raises.
From the caller's side the errors are usually self-describing: Puppet prints the offending value and the full allowed list, matplotlib lists every supported value and even hints when quotes are part of the string, and Hibernate's int-coercion failure prints the setting name, the raw value, and the value's concrete class. Timing varies by library. Most validators run eagerly so a daemon fails before serving traffic, but some are lazy: flow-remove-types rejects a bad includes/excludes option only on the first require() of a JS file, openapi-generator checks mergeConflictStrategy only when mergeMode is DEEP (a bad value passes silently in REF mode), and chroma validates query_config only on the embed_query path. Passing startup is therefore not proof that a config is valid.
The rules themselves differ per library, so the same-looking value can pass one validator and fail another. Case handling is a common trap: fluentd accepts only lowercase true/false/yes/no, while Hibernate's TCCL precedence and Maven's reference types accept any case, and openapi-generator normalizes case but never trims whitespace — nor does Maven. Boolean spellings diverge too: hadoop-tos and fluentd reject 1/0, on/off, and YES because only the literal spellings pass. Even the failure mode varies: most libraries throw, but Maven warns and falls back to a default reference type, and siyuan's update-channel reader silently falls back to "stable" while only the setter is strict.
Bad values enter config through predictable channels: hand edits and copy-paste (smart quotes from documentation, quoted values in matplotlibrc or style files), env vars and templating (WEB_CONCURRENCY set to "two", trailing commas in comma-separated host lists, a generic FREQUENCY variable fed into an enum-valued setting), wholesale migration from older versions or other systems (Puppet 3 configs, legacy checksum names, the literal "after" Hibernate rejects), config-generation code that skips validation (duplicate entries in concatenated lists, blank map keys, empty list segments), and drift between client and server (AFFiNE CalDAV preset ids cached from an older server configuration).
Common causes
- Value not in the allowed set. The setting accepts a fixed list of strings and the configured value is not one of them: an unsupported option ('websocket' as a Workerman transport, 'lz4' compression in Neon, ':epool' in Puma) or an invented one (OVERWRITE as a merge-conflict strategy). The error message usually prints the full allowlist.
- Near-miss spelling or wrong case. Misspelled or wrongly-cased tokens such as 'subquerry', 'deprecation' (singular), or 'TRUE' fail exact matching. Case sensitivity is library-specific: fluentd matches strictly lowercase, Hibernate and Maven accept any case.
- Stray whitespace or quotes. Trailing spaces in XML property values, quotes that become part of the value in matplotlibrc or style files, smart quotes pasted from docs, and untrimmed MAVEN_OPTS entries. Maven and openapi-generator normalize case but never trim whitespace.
- Wrong type or shape. A String where an instance is required (Hibernate's bytecodeprovider.instance), a Long where an int setting is read, an array where a single glob or RegExp is accepted (flow-remove-types), or '2.5'/'two' where an integer or :auto is required (Puma workers).
- Boolean written as 1/0, on/off, or other truthy spellings. Some validators accept only literal spellings: hadoop-tos booleans must be exactly true or false, and fluentd in strict mode accepts only lowercase true/false/yes/no (plus empty string). '1', 'on', 'YES', and 'True ' all fail.
- Number out of range. Zero or negative values where a positive number is required: --max-workers 0 in Flow, priority-levels=0 in Hadoop's FairCallQueue, a negative maxMemory in LightWeightGSet.computeCapacity.
- Config-generation bugs. Machine-assembled values skip the checks humans make: concatenated provider lists with duplicates (Chroma ONNX providers), blank map keys from user input (siyuan actionEffects), empty segments from trailing commas (GitNexus allowlist), and generic templates fed into enum-valued variables (litellm MAVVRIK_FOCUS_FREQUENCY).
- Stale or mismatched identifiers. A client sends an identifier the server's current configuration no longer defines, such as an AFFiNE CalDAV providerPresetId after the operator renamed or removed the preset.
What usually fixes it
- Treat the error message as the allowlist. Most messages in this family print the valid values verbatim (Puppet, matplotlib, Puma, CanCan). Copy one exactly — same case, spelling, and separators — instead of guessing or paraphrasing.
- Fix the source of the value, not the symptom. The message names the property key and echoes the raw value; trace that entry back through the chain (core-site.xml, .env, docker-compose, hiera data, CI variables, templates) and correct it there so the fix survives redeploys.
- Normalize values before the validator sees them. Trim whitespace and quotes, match the expected case, convert types explicitly (Integer(...) in Ruby, String.valueOf or int literals in Java maps), and dedupe order-sensitive lists while preserving priority order.
- Exercise the config before deploy. Use dry-run modes (fluentd --dry-run, deno publish --dry-run), lint enum-valued env vars in CI, and add bootstrap smoke tests such as building the SessionFactory in CI. Remember the lazy validators: openapi-generator skips the check in REF mode and flow-remove-types fails only on first require, so a green startup proves nothing.
- Prefer defaults and name-based settings. Omitting an optional setting usually selects a sane default (Hibernate TCCL precedence, litellm's daily frequency), and name-based alternatives exist alongside type- or instance-specific ones (hibernate.bytecode.provider instead of ...instance). Never use 0 or an empty string to mean 'auto' — omit the setting.
- Validate dynamic values against the live allowlist. When values come from another system at runtime, fetch the authoritative list — AFFiNE's provider presets from the server, CanCan.valid_accessible_by_strategies, NIO::Selector.backends — instead of hardcoding a list that can drift.
Go deeper
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Documented occurrences
- Memory " + maxMemory + " must be greater than or equal to 0 (apache/hadoop)
- #{name}: invalid bool value: #{str} (fluent/fluentd)
- update channel is invalid (siyuan-note/siyuan)
- --allow-insecure-connection / GITNEXUS_ALLOW_INSECURE_CONNECTION entries must be exact hostnames or IP addresses (abhigyanpatwari/GitNexus)
- Unknown TcclLookupPrecedence - {} (hibernate/hibernate-orm)
- Failed to parse value %s as %s, property key %s (apache/hadoop)
- unsupported IO selector backend: #{backend} (available backends: #{valid_backends.join(', ')}) (puma/puma)
- {unsup:?} is not implemented for background color. Use e.g. `width = '100%'` instead (wezterm/wezterm)
- Cannot disable unrecognized warning types '%{invalid}'. Valid values are '%{values}'. (puppetlabs/puppet)
- Invalid value '%{value}' for parameter %{name}. Allowed values are '%{allowed_values}' (puppetlabs/puppet)
- Invalid task: {task} (chroma-core/chroma)
- Unknown reference type for {}: {}, using default (apache/maven)
- Cannot represent compiler option '{name}' as a generated JSX pragma. (denoland/deno)
- "Requested queues (" + aNumQueues + ") must be greater than zero." (apache/hadoop)
- max_workers should be positive (facebook/flow)
- workers must be an Integer or :auto (puma/puma)
- caldav_provider_not_found: GraphQL bad request, code: caldav_provider_not_found, CalDAV provider is not available. (toeverything/AFFiNE)
- {s!r} is not a valid value for {self.key}; supported values are {[*self.valid.values()]} (matplotlib/matplotlib)
- Could not determine how to handle configuration value [name=${name}, value=${value}(${value.getClass().getName()})] as int (hibernate/hibernate-orm)
- config.actionEffects contains an empty action (siyuan-note/siyuan)
…and 113 more across the corpus — use search.
Honest provenance: generated on 2026-08-22 from AI-assisted analysis of the linked records. See how records are made.