projectdiscovery/nuclei · error

kerberos client is not initialized

Error message

kerberos client is not initialized

What it means

kerberos.SendToKDC requires a fully constructed Client: a non-nil goja runtime hook (nj), a parsed Krb5Config, and a non-empty Realm. The guard fails when the client is nil or any internal field is unset, which in practice means the Client was not created through new kerberos.Client(domain) inside a nuclei JavaScript execution.

Source

Thrown at pkg/js/libs/kerberos/sendtokdc.go:31

	"strings"
	"time"

	"github.com/jcmturner/gokrb5/v8/messages"
	"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
)

// sendtokdc.go deals with actual sending and receiving responses from KDC
// SendToKDC sends a message to the KDC and returns the response.
// It first tries to send the message over TCP, and if that fails, it falls back to UDP.(and vice versa)
// @example
// ```javascript
// const kerberos = require('nuclei/kerberos');
// const client = new kerberos.Client('acme.com');
// const response = kerberos.SendToKDC(client, 'message');
// ```
func SendToKDC(kclient *Client, msg string) (string, error) {
	if kclient == nil || kclient.nj == nil || kclient.Krb5Config == nil || kclient.Realm == "" {
		return "", fmt.Errorf("kerberos client is not initialized")
	}
	if kclient.config.timeout == 0 {
		kclient.config.timeout = 5 // default timeout 5 seconds
	}
	var response []byte
	var err error

	response, err = sendToKDCTcp(kclient, msg)
	if err == nil {
		// if it related to tcp
		bin, err := CheckKrbError(response)
		if err == nil {
			return string(bin), nil
		}
		// if it is krb error no need to do udp
		if e, ok := err.(messages.KRBError); ok {
			return string(response), e
		}

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Create the client first: const client = new kerberos.Client('acme.com'); then call kerberos.SendToKDC(client, msg)
  2. Pass a non-empty, plain domain (FQDN) so the Realm resolves during construction
  3. Never rebuild the Client from plain data; always go through the constructor so Krb5Config and runtime hooks initialize

Example fix

// before
const resp = kerberos.SendToKDC(client, msg); // client was a plain object or undefined

// after
const client = new kerberos.Client('acme.com');
const resp = kerberos.SendToKDC(client, msg);
Defensive patterns

Strategy: validation

Validate before calling

const kerberos = require('nuclei/kerberos');
const domain = 'acme.com';
if (!domain) throw new Error('domain is required');
const client = new kerberos.Client(domain);
const resp = kerberos.SendToKDC(client, msg);

Type guard

function isKerberosClient(c) {
  return c instanceof require('nuclei/kerberos').Client;
}

Prevention

When it happens

Trigger: kerberos.SendToKDC(null, msg); creating the client with an empty domain string so Realm stays empty; passing a plain JS object or re-hydrated JSON instead of a constructor-built Client; calling SendToKDC before the constructor finished initialization.

Common situations: Templates that deserialize a saved client state; refactoring that inlines the send call and drops the constructor; passing the domain with a trailing dot or '@' format the constructor does not normalize.

Related errors


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