projectdiscovery/nuclei · error

spn is required for silver ticket

Error message

spn is required for silver ticket

What it means

createSilverTicket refuses requests whose SPN field is empty. A silver ticket is a service ticket encrypted with the service account's key for one specific SPN; without an SPN there is nothing to forge against, so the request is rejected before any config is built.

Source

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

	outputFile, err := exportOutputFile(call.Argument(1))
	if err != nil {
		nj.ThrowError(err)
		return goja.Undefined()
	}

	ticket, err := createSilverTicket(nj.ExecutionId(), req, outputFile)
	if err != nil {
		nj.ThrowError(err)
		return goja.Undefined()
	}

	return vm.ToValue(ticket)
}

func createSilverTicket(executionID string, req TicketRequest, outputFile string) (*Ticket, error) {
	if req.SPN == "" {
		return nil, fmt.Errorf("spn is required for silver ticket")
	}

	cfg, err := buildConfig(executionID, req, outputFile)
	if err != nil {
		return nil, err
	}

	if cfg.OutputFile == "" {
		cfg.OutputFile = "-"
	}

	return createTicket(cfg)
}

func createTicket(cfg *gpkrb.TicketConfig) (*Ticket, error) {
	res, err := gpkrb.CreateTicket(cfg)
	if err != nil {
		return nil, err

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Add the target SPN in service/class format, e.g. spn: 'cifs/server01.acme.local'
  2. If you intended a TGT, use CreateGoldenTicket instead, which takes no SPN
  3. Supply the NT hash or AES key of the service account that owns the SPN (machine account for cifs/host SPNs)

Example fix

// before
const t = krb.CreateSilverTicket({
  username: 'Administrator',
  domain: 'acme.local',
  domain_sid: 'S-1-5-21-...',
  nthash: '31d6cfe0d16ae931b73c59d7e0c089c0',
});

// after
const t = krb.CreateSilverTicket({
  username: 'Administrator',
  domain: 'acme.local',
  domain_sid: 'S-1-5-21-...',
  nthash: '31d6cfe0d16ae931b73c59d7e0c089c0',
  spn: 'cifs/server01.acme.local',
});
Defensive patterns

Strategy: validation

Validate before calling

if (!req.spn) {
  throw new Error('a silver ticket needs the target SPN, e.g. cifs/server01.acme.local');
}
const t = krb.CreateSilverTicket(req);

Type guard

function isValidSilverRequest(r) {
  return r != null && typeof r.spn === 'string' && r.spn.length > 0 && /^[a-z0-9-]+\//i.test(r.spn);
}

Prevention

When it happens

Trigger: Calling krb.CreateSilverTicket({username, domain, domain_sid, nthash}) with no spn key; passing an object whose spn property is an empty string or undefined; copy-pasting a golden-ticket example (which needs no SPN) into CreateSilverTicket.

Common situations: Confusing golden (TGT, krbtgt hash, no SPN) with silver (TGS, service hash, SPN required) workflows; JSON-driven templates where the spn key is optional in the schema and omitted.

Related errors


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