projectdiscovery/nuclei · error

invalid TicketRequest: %w

Error message

invalid TicketRequest: %w

What it means

Thrown by exportTicketRequest in krbforge when goja's vm.ExportTo cannot convert the first argument of CreateGoldenTicket/CreateSilverTicket into the TicketRequest struct. ExportTo fails when the value is not a plain object (string, number, array, null-as-argument) or when a field has an incompatible type, e.g. user_id supplied as string '1010' instead of number 1010.

Source

Thrown at pkg/js/libs/krbforge/krbforge.go:242

		normalized = filepath.Join(config.DefaultConfig.GetTemplateDir(), normalized)
	}

	normalized, err := filepath.Abs(normalized)
	if err != nil {
		return "", fmt.Errorf("normalize output file %q: %w", outputFile, err)
	}

	if filepathutil.IsPathWithinDirectory(normalized, config.DefaultConfig.GetTemplateDir()) {
		return normalized, nil
	}

	return "", fmt.Errorf("path %v is outside nuclei-template directory and -allow-local-file-access is not enabled", outputFile)
}

func exportTicketRequest(vm *goja.Runtime, value goja.Value) (TicketRequest, error) {
	var req TicketRequest
	if err := vm.ExportTo(value, &req); err != nil {
		return req, fmt.Errorf("invalid TicketRequest: %w", err)
	}
	return req, nil
}

func exportOutputFile(value goja.Value) (string, error) {
	if goja.IsUndefined(value) || goja.IsNull(value) {
		return "", nil
	}
	outputFile, ok := value.Export().(string)
	if !ok {
		return "", fmt.Errorf("outputFile must be a string")
	}
	return outputFile, nil
}

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Pass a plain object literal whose keys match the documented field names (Username, Domain, DomainSID, NTHash, AESKey, SPN, UserID, PrimaryGroupID, Groups, ExtraSIDs, DurationHours, KVNO, OutputFile)
  2. Cast numeric fields with Number(...) before the call: user_id: Number(userIdVar)
  3. Ensure array fields are real arrays of the right element type (Groups: [512, 513])
  4. If the request came from JSON.parse, validate its shape against the expected schema first

Example fix

// before
krb.CreateGoldenTicket({
  Username: 'Administrator',
  Domain: 'acme.local',
  DomainSID: 'S-1-5-21-...',
  UserID: templateVar, // string like '500' -> ExportTo fails
});

// after
krb.CreateGoldenTicket({
  Username: 'Administrator',
  Domain: 'acme.local',
  DomainSID: 'S-1-5-21-...',
  UserID: Number(templateVar),
});
Defensive patterns

Strategy: type-guard

Type guard

function isTicketRequest(v) {
  if (typeof v !== 'object' || v === null || Array.isArray(v)) return false;
  for (const k of ['Username','Domain','DomainSID','NTHash','AESKey','SPN','OutputFile']) {
    if (k in v && typeof v[k] !== 'string') return false;
  }
  for (const k of ['UserID','PrimaryGroupID','DurationHours','KVNO']) {
    if (k in v && typeof v[k] !== 'number') return false;
  }
  if ('Groups' in v && !Array.isArray(v.Groups)) return false;
  return true;
}
if (!isTicketRequest(req)) throw new Error('bad ticket request shape');

Try / catch

try {
  krb.CreateGoldenTicket(req);
} catch (e) {
  if (String(e).includes('invalid TicketRequest')) {
    // log the offending object shape for template debugging
    log('TicketRequest rejected: ' + to_json(req));
  }
}

Prevention

When it happens

Trigger: krb.CreateGoldenTicket('admin') or passing an array/JSON string; krab.CreateSilverTicket({user_id: '500', ...}) where the struct expects uint32; nested wrong types such as groups: '512' instead of groups: [512].

Common situations: Building the request from a template extractor/variable that yields strings and forgetting to cast to numbers; passing JSON.parse output of a differently-shaped object; typos are NOT caught here (unknown keys are ignored, they fail later as empty required fields).

Related errors


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