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

  1. Pass one object literal with the documented fields: Username, Domain, KDCHost, SPN, Password (or NTHash), optionally TargetUser and Format
  2. Coerce values with String(...) when they originate from extractors or LDAP entries
  3. 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

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


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/fd972300b7d8e183. Report an issue: GitHub.