golang/go · error

crypto/dsa: parameters not set up before generating key

Error message

crypto/dsa: parameters not set up before generating key

What it means

GenerateKey requires that the PrivateKey's Parameters (P, Q, G) already be set, normally by a prior successful call to GenerateParameters. If any of priv.P, priv.Q, or priv.G is nil, the function returns this error immediately (after the FIPS check), because it cannot compute a valid key without domain parameters.

Source

Thrown at src/crypto/dsa/dsa.go:170

		if g.Cmp(one) == 0 {
			h.Add(h, one)
			continue
		}

		params.G = g
		return nil
	}
}

// GenerateKey generates a public&private key pair. The Parameters of the
// [PrivateKey] must already be valid (see [GenerateParameters]).
func GenerateKey(priv *PrivateKey, rand io.Reader) error {
	if fips140only.Enforced() {
		return errors.New("crypto/dsa: use of DSA is not allowed in FIPS 140-only mode")
	}

	if priv.P == nil || priv.Q == nil || priv.G == nil {
		return errors.New("crypto/dsa: parameters not set up before generating key")
	}

	x := new(big.Int)
	xBytes := make([]byte, priv.Q.BitLen()/8)

	for {
		_, err := io.ReadFull(rand, xBytes)
		if err != nil {
			return err
		}
		x.SetBytes(xBytes)
		if x.Sign() != 0 && x.Cmp(priv.Q) < 0 {
			break
		}
	}

	priv.X = x
	priv.Y = new(big.Int)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Call dsa.GenerateParameters(&priv.Parameters, rand.Reader, sizes) first and check its error.
  2. Only call GenerateKey after parameters are confirmed valid.
  3. If loading parameters from elsewhere, populate priv.P, priv.Q, priv.G explicitly before GenerateKey.

Example fix

// before
var priv dsa.PrivateKey
dsa.GenerateKey(&priv, rand.Reader) // P, Q, G are nil
// after
var priv dsa.PrivateKey
dsa.GenerateParameters(&priv.Parameters, rand.Reader, dsa.L2048N256)
dsa.GenerateKey(&priv, rand.Reader)
Defensive patterns

Strategy: validation

Validate before calling

func genDSAKey(rand io.Reader) (*dsa.PrivateKey, error) {
    var priv dsa.PrivateKey
    if err := dsa.GenerateParameters(&priv.Parameters, rand, dsa.L2048N256); err != nil {
        return nil, err
    }
    if priv.P == nil || priv.Q == nil || priv.G == nil {
        return nil, errors.New("DSA parameters not generated")
    }
    if err := dsa.GenerateKey(&priv, rand); err != nil {
        return nil, err
    }
    return &priv, nil
}

Type guard

func dsaParamsSet(p *dsa.PrivateKey) bool {
    return p != nil && p.P != nil && p.Q != nil && p.G != nil
}

Prevention

When it happens

Trigger: Calling dsa.GenerateKey on a freshly allocated *dsa.PrivateKey whose Parameters were never populated; skipping the GenerateParameters step; failed GenerateParameters (error ignored) followed by GenerateKey.

Common situations: Copy-paste missing the parameter-generation step; ignoring the error from GenerateParameters; reusing a zero-value PrivateKey struct.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/45be56a326ff852a. Report an issue: GitHub.