windmill-labs/windmill · error
WORKER_SUFFIX must only contain ASCII letters, digits and un
Error message
WORKER_SUFFIX must only contain ASCII letters, digits and underscores, got '{label}' What it means
`create_labelled_worker_suffix` builds the per-worker name suffix from the WORKER_SUFFIX label. Windmill validates that the label consists solely of ASCII letters, digits and underscores, because it becomes part of the worker's database primary key and filesystem directory path; other characters could break naming or path handling. Any label containing spaces, dashes, dots, slashes, or non-ASCII characters triggers this error at worker startup.
Source
Thrown at backend/windmill-common/src/utils.rs:417
None if EXIT_AFTER_N_JOBS.is_some() => create_stable_worker_suffix(hostname, index),
None => create_default_worker_suffix(hostname),
})
}
/// The operator's label only has to tell the worker processes of one host apart, so it is
/// appended to the stable suffix rather than replacing it: the digest is what keeps two hosts
/// whose names end on the same segment (`worker-east-1`, `worker-west-1`) from sharing an
/// identity, and it already folds in the worker index. A `-` in the label would add a segment
/// to the worker name, which [`retrieve_common_worker_prefix`] reads as the part to strip;
/// rejected rather than rewritten, since the point of the label is that two different ones
/// give two different names.
fn create_labelled_worker_suffix(
hostname: &str,
label: &str,
index: usize,
) -> anyhow::Result<String> {
if !label.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {
return Err(anyhow::anyhow!(
"WORKER_SUFFIX must only contain ASCII letters, digits and underscores, got '{label}'"
));
}
// The worker name is a `VARCHAR(255)` primary key and a component of the worker
// directory's path: a label long enough to blow either only surfaces at the initial ping,
// which the worker `expect`s.
if label.len() > MAX_WORKER_SUFFIX_LABEL_LEN {
return Err(anyhow::anyhow!(
"WORKER_SUFFIX must be at most {MAX_WORKER_SUFFIX_LABEL_LEN} characters, got {}",
label.len()
));
}
Ok(format!(
"{}_{label}",
create_stable_worker_suffix(hostname, index)
))
}
View on GitHub (pinned to e474e8803c)
Solutions
- Edit WORKER_SUFFIX to contain only ASCII letters, digits, and underscores (e.g. `my-worker` → `my_worker`).
- Remove trailing/leading whitespace or quotes picked up from the env file or shell quoting.
- If the label is generated from a hostname or container name, sanitize it by replacing non-alphanumeric characters with underscores before export.
- Restart the worker; this error is fatal at startup by design.
Example fix
// before (docker-compose env) WORKER_SUFFIX=worker-eu-1 // after WORKER_SUFFIX=worker_eu_1
Defensive patterns
Strategy: validation
Validate before calling
const label = process.env.WORKER_SUFFIX ?? "";
if (!/^[A-Za-z0-9_]*$/.test(label)) {
throw new Error(`WORKER_SUFFIX '${label}' must only contain ASCII letters, digits and underscores`);
} Type guard
function isValidWorkerSuffixLabel(label) {
return typeof label === "string" && /^[A-Za-z0-9_]+$/.test(label);
} Try / catch
try {
startWorker({ suffix: process.env.WORKER_SUFFIX });
} catch (e) {
if (String(e).includes("WORKER_SUFFIX must only contain")) {
console.error("Sanitize WORKER_SUFFIX: replace [-. ] with _");
process.env.WORKER_SUFFIX = process.env.WORKER_SUFFIX.replace(/[^A-Za-z0-9_]/g, "_");
return startWorker({ suffix: process.env.WORKER_SUFFIX });
}
throw e;
} Prevention
- Use underscores, never hyphens or dots, in WORKER_SUFFIX.
- Sanitize machine-generated labels (hostnames, container names) through .replace(/[^A-Za-z0-9_]/g, "_").
- Add a deployment-time lint that asserts WORKER_SUFFIX matches ^[A-Za-z0-9_]+$.
- Avoid shell/env quoting pitfalls that can inject whitespace into the value.
When it happens
Trigger: Starting a windmill worker with WORKER_SUFFIX set to a value containing characters outside [A-Za-z0-9_] — e.g. `WORKER_SUFFIX=my-worker`, `WORKER_SUFFIX=worker.eu`, `WORKER_SUFFIX=worker 1`, or a unicode label — when `resolve_worker_suffix` calls `create_labelled_worker_suffix`.
Common situations: Operators using hyphens (a common habit from container/host naming) in WORKER_SUFFIX; copy-pasting a hostname or docker container name (which contain dashes/dots) into WORKER_SUFFIX; templated deployments interpolating values with punctuation.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- WORKER_SUFFIX must be at most {MAX_WORKER_SUFFIX_LABEL_LEN}
- EXIT_AFTER_N_JOBS must be a positive integer (or 0 to disabl
- Invalid AI agent provider configuration: ${errors.join('\n')
- API key or resource path is required
- Missing a model to test
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/35b3ca46c50c4f22.
Report an issue: GitHub.