NAME
Punk::SAML::Error - what a refusal throws
DESCRIPTION
Every refusal in this distribution throws one of these: a blessed hashref with a code and a message.
eval { Punk::SAML::Response->verify($bytes, %opts) };
if (ref $@) {
warn "saml refused: $@->{code}";
}
code
The interface. The route logs it, the tests assert on it, this page lists it, and an operator greps for it. Codes are added, never reworded.
message
For the log. It never reaches the browser: a verifier that tells the far side which check it failed is telling an attacker which one to work on next. Every refusal produces the same page.
CODES
xml_parse-
the document is not well-formed XML, carries a DOCTYPE, or has two elements with the same ID.
xml_shape-
the document parsed but is not the shape a Response must have: a wrong root, a wrong Version, no Assertion or more than one, no Subject, no NameID, no bearer SubjectConfirmation, or no AuthnStatement.
bad_base64-
the SAMLResponse field is over max_response, or is not strict standard base64.
bad_datetime-
a timestamp is not an xs:dateTime in UTC. Core section 1.3.3 requires UTC, and an offset is refused rather than converted.
no_signature-
nothing is signed that require_signed requires to be.
bad_signature-
a signature is present and does not verify, for any reason: a Reference naming another element, a refused transform, or no configured key verifying it.
bad_digest-
the reference digest does not match the element the signature covers, which is what an edited assertion looks like.
alg_refused-
a SignatureMethod or DigestMethod this plugin does not accept, including rsa-sha1 and, on the digest side, SHA-1 without allow_sha1.
unknown_issuer-
the Issuer is not the provider's entity id.
no_key-
no signing certificate is configured for the provider.
expired-
the assertion or its subject confirmation window has passed, allowing skew.
not_yet_valid-
the assertion is not valid yet, allowing skew. Usually a clock difference larger than skew.
bad_audience-
no AudienceRestriction names this application.
bad_destination-
the Destination or the SubjectConfirmationData Recipient is not this application's assertion consumer URL.
bad_in_response_to-
the Response answers a different login, or answers one this application has no record of starting.
replay-
the assertion has been presented before.
unsolicited-
there is no flow record and allow_idp_initiated is off.
encrypted_assertion-
the Response carries an EncryptedAssertion, which is refused rather than decrypted.
status-
the provider returned a StatusCode other than Success. The nested code and any StatusMessage are in the message.
config-
a provider was misconfigured or its metadata could not be used.
SEE ALSO
Punk::Plugin::SAML, whose WHAT IS CHECKED section gives these in the order they are checked.
AUTHOR
LNATION, <email at lnation.org>
LICENSE AND COPYRIGHT
This software is Copyright (c) 2026 by LNATION.
This is free software, licensed under the Artistic License 2.0.