certbot/certbot · error · ValueError
The supplied code: %s is not a known ACME error code
Error message
The supplied code: %s is not a known ACME error code
What it means
Raised by acme.messages.Error.with_code when the given code string is not a key of the ERROR_CODES mapping of known ACME error codes. The method exists to construct typed ACME errors (e.g. 'dnssec', 'connection') by prefixing the code with the ACME urn prefix, so it refuses unknown codes.
Source
Thrown at acme/src/acme/messages.py:156
'identifier', decoder=Identifier.from_json, omitempty=True)
subproblems: Optional[tuple['Error', ...]] = jose.field('subproblems', omitempty=True)
# Mypy does not understand the josepy magic happening here, and falsely claims
# that subproblems is redefined. Let's ignore the type check here.
@subproblems.decoder # type: ignore
def subproblems(value: list[dict[str, Any]]) -> tuple['Error', ...]: # pylint: disable=no-self-argument,missing-function-docstring
return tuple(Error.from_json(subproblem) for subproblem in value)
@classmethod
def with_code(cls, code: str, **kwargs: Any) -> 'Error':
"""Create an Error instance with an ACME Error code.
:str code: An ACME error code, like 'dnssec'.
:kwargs: kwargs to pass to Error.
"""
if code not in ERROR_CODES:
raise ValueError("The supplied code: %s is not a known ACME error"
" code" % code)
typ = ERROR_PREFIX + code
# Mypy will not understand that the Error constructor accepts a named argument
# "typ" because of josepy magic. Let's ignore the type check here.
return cls(typ=typ, **kwargs)
@property
def description(self) -> Optional[str]:
"""Hardcoded error description based on its type.
:returns: Description if standard ACME error or ``None``.
:rtype: str
"""
return ERROR_TYPE_DESCRIPTIONS.get(self.typ)
@property
def code(self) -> Optional[str]:View on GitHub (pinned to 2b817be146)
Solutions
- Check the code against acme.messages.ERROR_CODES and use a registered code such as 'dnssec', 'malformed', 'serverInternal'
- If the code comes from a real server response, parse the error from the response JSON directly (Error.from_json/typ field) instead of with_code
- Upgrade the acme package so newer error codes are included in ERROR_CODES
Example fix
# before
Error.with_code('dnsSEC') # ValueError
# after
from acme import messages
assert 'dnssec' in messages.ERROR_CODES
messages.Error.with_code('dnssec') Defensive patterns
Strategy: validation
Validate before calling
from acme import messages
if code not in messages.ERROR_CODES:
raise KeyError(f'unknown ACME error code {code}; available: {sorted(messages.ERROR_CODES)}') Type guard
from acme import messages
def is_known_acme_code(code: str) -> bool:
return code in messages.ERROR_CODES Try / catch
try:
err = messages.Error.with_code(code)
except ValueError:
err = messages.Error(typ='urn:ietf:params:acme:error:' + code, detail='...') Prevention
- Check ERROR_CODES membership in test helpers
- Upgrade acme when CAs introduce new error types
When it happens
Trigger: Calling Error.with_code('someUnknownCode', ...) where the code is not registered in acme.messages.ERROR_CODES — e.g. typo like 'dnsSEC', a new RFC 8555 error type the installed acme version predates, or a vendor-specific code.
Common situations: Writing tests that simulate ACME server errors with an invented or misspelled code; handling a CA-specific error type not in the library's catalogue; upgrading servers that emit new error types while the client library is older.
Related errors
- Invalid private key type: {type(private_key)}
- At least one of domains or ipaddrs parameter need to be not
- Encoding must be PEM or DER
- Invalid value for hmac_alg: {hmac_alg}. Expected one of: {su
- Could not bind to IPv4 or IPv6.
AI-assisted analysis of certbot/certbot@2b817be146 (2026-08-27).
Data as JSON: /api/errors/c47aaaddd25705ef.
Report an issue: GitHub.