projectdiscovery/nuclei · error
invalid KerberoastRequest: %w
Error message
invalid KerberoastRequest: %w
What it means
Thrown by krbroast.Kerberoast when vm.ExportTo cannot convert call.Argument(0) into the KerberoastRequest struct. The single argument must be a plain object; it fails for non-object values and for fields whose JS types do not map onto the Go struct (all fields are strings).
Source
Thrown at pkg/js/libs/krbroast/krbroast.go:132
//
// const r = krb.Kerberoast({
// Username: 'lowpriv',
// Password: 'P@ss',
// Domain: 'acme.local',
// KDCHost: 'dc01.acme.local',
// SPN: 'MSSQLSvc/sql01.acme.local:1433',
// TargetUser: 'svc_sql',
// });
//
// log(r.Hash);
// ```
func Kerberoast(call goja.FunctionCall, vm *goja.Runtime) goja.Value {
nj := utils.NewNucleiJS(vm)
nj.ObjectSig = "Kerberoast(request)"
var req KerberoastRequest
if err := vm.ExportTo(call.Argument(0), &req); err != nil {
nj.ThrowError(fmt.Errorf("invalid KerberoastRequest: %w", err))
}
if req.Username == "" || req.Domain == "" || req.KDCHost == "" || req.SPN == "" {
nj.ThrowError(fmt.Errorf("Username, Domain, KDCHost and SPN are required")) //nolint
}
if req.Password == "" && req.NTHash == "" {
nj.ThrowError(fmt.Errorf("either Password or NTHash must be supplied"))
}
execID := nj.ExecutionId()
if execID == "" {
nj.ThrowError(fmt.Errorf("krbroast: no executionId on goja runtime"))
}
if !protocolstate.IsHostAllowed(execID, req.KDCHost) {
nj.ThrowError(protocolstate.ErrHostDenied.Msgf(req.KDCHost))
}
target := req.TargetUser
if target == "" {View on GitHub (pinned to 265b3a3dec)
Solutions
- Pass one object literal with the documented fields: Username, Domain, KDCHost, SPN, Password (or NTHash), optionally TargetUser and Format
- Coerce values with String(...) when they originate from extractors or LDAP entries
- Unwrap array-valued attributes from search results before building the request
Example fix
// before
krb.Kerberoast('svc_sql', 'acme.local', 'dc01', 'MSSQLSvc/sql01:1433'); // wrong shape
// after
krb.Kerberoast({
Username: 'user',
Password: 'pass',
Domain: 'acme.local',
KDCHost: 'dc01.acme.local',
SPN: 'MSSQLSvc/sql01.acme.local:1433',
}); Defensive patterns
Strategy: type-guard
Type guard
function isKerberoastRequest(v) {
return typeof v === 'object' && v !== null && !Array.isArray(v)
&& ['Username','Domain','KDCHost','SPN'].every(k => typeof v[k] === 'string')
&& (!('Password' in v) || typeof v.Password === 'string')
&& (!('NTHash' in v) || typeof v.NTHash === 'string');
}
if (!isKerberoastRequest(req)) throw new Error('bad Kerberoast request'); Try / catch
try {
const r = krb.Kerberoast(req);
} catch (e) {
if (String(e).includes('invalid KerberoastRequest')) {
log('request shape invalid: ' + to_json(req));
}
} Prevention
- One object argument only; all fields strings
- Unwrap arrays from LDAP entries (e.g. entry.sAMAccountName[0])
- Validate the shape next to where you build it, not after the failure
When it happens
Trigger: krb.Kerberoast('svc_sql') or passing a comma-separated argument list instead of one object; {Username: 123} numeric fields; passing an entry object from an LDAP search whose attribute values are arrays.
Common situations: Feeding values straight from nuclei/ldap GetADUserKerberoastable entries without unwrapping; using snake_case keys that silently map to empty (that fails later as error 267, not here); passing a JSON string that was not parsed.
Related errors
- invalid ASRepRoastRequest: %w
- invalid TicketRequest: %w
- Username, Domain and KDCHost are required
- Username, Domain, KDCHost and SPN are required
- either Password or NTHash must be supplied
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/fd972300b7d8e183.
Report an issue: GitHub.