A failed Certipy command does not by itself identify a Certipy bug. The failure may come from local syntax, name resolution, CA policy, certificate contents, KDC support, certificate mapping, or an earlier relay stage.
Use this page with the command that failed. Replace every <PLACEHOLDER> with a value from the authorized environment before running it; an unchanged angle bracket can be interpreted by the shell as input or output redirection. Preserve the original command, change one input at a time, and record whether the failure moves to a different stage.
Start with the first stage that did not produce its expected output:
Request failed
├─ option or parsing error → installed version and subcommand help
├─ connection error → DC, CA, protocol, DNS, and RPC path
├─ TEMPLATE_DENIED → requesting identity and Enroll rights
└─ taken under submission → pending CA approval
Certificate issued, authentication failed
├─ inconsistent key purpose → certificate is not valid for PKINIT
├─ principal or name mismatch → UPN, DNS identity, and selected account
├─ padata type unsupported → selected DC is not accepting PKINIT
└─ client not trusted → chain trust, SID, and strong mapping
Relay produced no usable certificate
├─ no inbound authentication → listener, routing, and coercion path
├─ inbound authentication, no CA request → relay target and protocol
├─ request denied → relayed identity and template rights
└─ certificate issued but unusable → authentication branch above
Record the evidence before changing anything
Resolve the installed command and record its version:
CERTIPY_BIN="$(command -v certipy || command -v certipy-ad)"
if [ -n "$CERTIPY_BIN" ]; then
"$CERTIPY_BIN" -v
"$CERTIPY_BIN" <SUBCOMMAND> -h
else
printf '%s\n' 'Certipy binary not found in PATH' >&2
fi
If the block reports that the binary was not found, resolve the installation or environment before diagnosing CA behavior.
If the normal output does not explain the failure, repeat the command with Certipy’s global debug option before the subcommand:
"$CERTIPY_BIN" -debug <SUBCOMMAND> <SAME_OPTIONS>
Retain the exact error, request ID, CA disposition, certificate identities, selected principal, and traceback. Redact domains, addresses, account names, SIDs, certificate subjects, and file paths before moving output into a public issue or shared note.
Write these values down separately:
DOMAIN_FQDN =
DC_IP =
DC_FQDN =
CA_FQDN =
CA_NAME =
TEMPLATE =
Use values from the current enumeration and failing command:
| Placeholder | Replace it with |
|---|---|
<SUBCOMMAND> |
The action that failed, such as req, auth, or relay |
<DC_IP> / <DC_FQDN> |
One specifically selected, in-scope domain controller |
<CA_FQDN> |
The DNS name of the host running the selected CA service |
<CA_NAME> |
The exact CA name reported by Certipy for that CA |
<TEMPLATE> |
The exact template associated with that CA in the enumeration output |
<CERTIFICATE> |
The PFX file produced or selected for the authentication test |
<ACCOUNT> / <DOMAIN_FQDN> |
The intended AD account and the AD DNS domain—not an email or external DNS domain unless they are actually the same |
<SAME_OPTIONS> |
The original options from the failing command, changed only as required for the single test being performed |
-dc-ip identifies the domain controller, -target identifies the CA host for a certificate request, -ca identifies the CA by name, and -template identifies the certificate template. A reachable DC does not prove that the CA name, CA host, or enrollment protocol is correct. Kerberos operations also depend on names, DNS, and time; replacing every hostname with an IP can create a second problem while hiding the first one.
CERTSRV_E_TEMPLATE_DENIED
This error means the CA did not permit the current requesting identity to enroll through that template. Check, in order:
- The identity Certipy actually used is the expected user or computer account.
- The selected template is enabled and published by the selected CA.
- That identity, or one of its effective groups, has Enroll permission.
- The template name and CA name came from the same enumeration result rather than from different environments or copied commands.
If the request was made through a relay, the requesting identity is the relayed principal printed by Certipy—not the account that started the listener or coercion tool.
Do not treat this error as evidence that Certipy needs to be downgraded. It is a CA policy result unless the same authorized request succeeds through another client under equivalent conditions and Certipy produces inconsistent protocol behavior.
A denied request can still return a request ID and prompt to save its private key. That detail matters in a specific CA-management workflow where an authorized certificate manager can later issue and retrieve the same request. It is not a general fix for missing enrollment rights, and the private key remains credential material.
Manager approval is a different state. A request that reports Taken under submission is pending, not CERTSRV_E_TEMPLATE_DENIED. Record its request ID and disposition instead of repeatedly submitting new requests. Approval, denial, and retrieval require separate authorization.
The certificate was issued, but certipy auth failed
Read the identity block printed before the KDC error:
Certificate identities:
SAN UPN: ...
SAN DNS Host Name: ...
SAN URL SID: ...
Security Extension SID: ...
Using principal: ...
Confirm that the certificate contains the identity expected for the account type and that Certipy selected the intended principal. A certificate filename is not evidence of what the certificate contains.
KDC_ERR_INCONSISTENT_KEY_PURPOSE
The KDC is rejecting the certificate for PKINIT client authentication. Check the template’s extended key usages and application policies. A certificate issued from a server-only template can be valid as a certificate while still being unsuitable for domain logon.
Do not describe every template that permits an alternate UPN as exploitable. The resulting certificate also needs a purpose accepted for authentication.
Principal not found or certificate name mismatch
Compare the SAN UPN or DNS identity with the principal Certipy selected. User certificates normally identify a user through a UPN; computer certificates commonly use a DNS identity and a machine account ending in $. Supplying both UPN and DNS values can cause the wrong identity to be selected if they describe different account types.
Certipy’s current auth command accepts explicit -username and -domain values when automatic extraction is ambiguous:
"$CERTIPY_BIN" auth \
-pfx '<CERTIFICATE>.pfx' \
-username '<ACCOUNT>' \
-domain '<DOMAIN_FQDN>' \
-dc-ip '<DC_IP>'
Explicit selection cannot make an unrelated certificate map to that account. It only removes ambiguity in the client-side choice.
KDC_ERR_PADATA_TYPE_NOSUPP
The selected domain controller is not accepting the PKINIT pre-authentication exchange. A common cause is that the DC does not have a suitable domain-controller certificate, but the error establishes the missing PKINIT capability, not the exact server configuration.
Confirm that the command reached the intended DC and record that DC’s identity. If another in-scope DC is selected, treat it as a separate test because certificate enrollment and PKINIT support may differ between DCs.
If the required operation is LDAP rather than obtaining a Kerberos TGT or NT hash, Certipy can attempt Schannel authentication:
"$CERTIPY_BIN" auth \
-pfx '<CERTIFICATE>.pfx' \
-dc-ip '<DC_IP>' \
-ldap-shell
This is an alternate authentication path, not a repair for PKINIT. It requires reachable LDAP over TLS and successful Schannel certificate mapping, and it does not produce the same result as Kerberos authentication.
KDC_ERROR_CLIENT_NOT_TRUSTED or mapping failure
Separate certificate trust from account mapping:
- Confirm the certificate is within its validity period and chains to the issuing CA expected for domain authentication.
- Compare the SAN UPN or DNS identity with the account type and the principal Certipy selected.
- Compare the SAN URL SID and security-extension SID, when present, with the intended account.
- Check the selected DC’s KDC and System events, when collection is authorized, for the server-side reason.
Certificate issuance proves that the CA processed the request; it does not prove that a domain controller will trust and strongly map the issued certificate.
Current Windows domain controllers enforce the certificate-binding changes documented in KB5014754. Weak UPN, subject, or issuer mappings that worked in an older environment may now be rejected. Do not recommend weakening KDC or Schannel mapping policy as a troubleshooting shortcut. Use the KDC and System event logs, when collection is authorized, to distinguish trust failure from name or SID mapping failure.
Relay is running, but no usable certificate appears
Troubleshoot the relay as a sequence. Do not jump directly to template changes.
No authentication reaches the listener
Check that Certipy reported a successful bind on the expected interface and port, that no other process owns the listener, and that the selected authentication source can route to it. Then verify the coercion or name-resolution condition required by that specific test. A silent listener is not evidence of a CA or template problem.
Authentication arrives, but no CA request is attempted
Use the last relay log message as the checkpoint. Confirm the configured CA host and enrollment protocol. ESC8 web enrollment and ESC11 RPC enrollment are different targets with different transport and security requirements. Verify reachability and the relevant endpoint before changing the template. Signing, channel binding, or another enforced protection may correctly prevent the relay; record that as the result rather than disabling a control outside the approved test plan.
The CA receives the request but denies it
The template must be published by that CA and enrollable by the relayed principal. Match the template to the verified account type:
| Relayed principal | Template starting point | Required verification |
|---|---|---|
| User | User or a custom user-authentication template |
Effective Enroll permission and an authentication purpose |
Member computer ending in $ |
Machine, Workstation, or a custom computer template |
Effective Enroll permission and correct DNS/account mapping |
| Domain controller computer account | A domain-controller authentication template | Confirm it is a DC and that the exact template is published and enrollable |
The account name is only a starting clue. Do not identify a domain controller from a hostname-like account name alone, and do not assume that a default template exists or is published in every environment.
A certificate is issued but cannot authenticate
The relay stage succeeded. Return to the certificate identity and KDC branches above. Changing the coercion method or restarting the listener will not correct an unsuitable EKU, an identity mismatch, missing PKINIT support, or strong mapping failure.
Decide whether it is a Certipy bug
Open a tool issue only after preserving enough evidence to distinguish unexpected client behavior from an environmental decision. A useful report includes:
- Exact Certipy version and installation source.
- Operating system and Python version.
- Full command with sensitive values replaced consistently.
- Complete error and
-debugtraceback. - Whether DNS names resolve to the intended DC and CA.
- Request ID and CA disposition, when a request reached the CA.
- Certificate identity block and selected principal, when issuance succeeded.
- Whether an equivalent authorized request behaves differently through another supported client.
A syntax change, CA denial, pending request, KDC capability gap, or enforced certificate-mapping policy is not a Certipy bug on its own.