owasp-amass/amass · error

improper mask used

Error message

improper mask used: %s

What it means

ExpandMask only understands specific mask characters (e.g. 'u' upper, 'd' digit, 'l' letters, 's' special); anything else after '?' hits the default branch and returns this error. It signals that the mask placeholder syntax is not recognized by this implementation.

Solutions

  1. Use only the supported placeholders: u, d, l, s
  2. Check config/wordlist.go for the exact maskLetters/maskSpecial/upper/digit sets
  3. Pre-validate mask strings before expansion

Example fix

// before
words, err := ExpandMask("?a?d")
// after
words, err := ExpandMask("?s?d")
Defensive patterns

Strategy: validation

Validate before calling

var validPlaceholders = map[byte]bool{'u':true,'d':true,'l':true,'s':true}
func isValidMaskSyntax(w string) bool {
  for i := 0; i < len(w); i++ { if w[i] == '?' && i+1 < len(w) && !validPlaceholders[w[i+1]] { return false } }
  return true
}

Type guard

func isSupportedPlaceholder(c byte) bool { return c=='u'||c=='d'||c=='l'||c=='s' }

Try / catch

words, err := ExpandMask(m)
if err != nil {
  if strings.HasPrefix(err.Error(), "improper mask used") {
    // report the unsupported placeholder and skip this entry
  }
  return err
}

Prevention

When it happens

Trigger: Calling ExpandMask with an unsupported placeholder such as ?a, ?h, or ?1 that the hashcat-style subset in this library does not implement.

Common situations: Copying hashcat masks that use the full hashcat charset into this simpler expander; typos like ?L or ?d?; invalid characters in a wordlist entry intended as a mask.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of owasp-amass/amass@79299dce87 (2026-09-06). Data as JSON: /api/errors/69eca36c5e2be5e3. Report an issue: GitHub.

Appendix: source

Thrown at config/wordlist.go:51

		return expanded, fmt.Errorf("exceeded maximum mask size (3): %s", word)
	}

	parts := strings.SplitN(word, "?", 2)
	if len(parts) > 1 {
		if len(parts[1]) > 0 {
			switch parts[1][0] {
			case 'a':
				chars = maskLetters + maskDigits + maskSpecial
			case 'd':
				chars = maskDigits
			case 'u':
				fallthrough
			case 'l':
				chars = maskLetters
			case 's':
				chars = maskSpecial
			default:
				return expanded, fmt.Errorf("improper mask used: %s", word)
			}
			for _, ch := range chars {
				newWord := parts[0] + string(ch) + parts[1][1:]
				nextRound, err := ExpandMask(newWord)
				if err != nil {
					return expanded, err
				}
				expanded = append(expanded, nextRound...)
			}
		}
	} else {
		expanded = append(expanded, word)
	}
	return expanded, nil
}

// ExpandMaskWordlist performs ExpandMask on a slice of words.
func ExpandMaskWordlist(wordlist []string) ([]string, error) {

View on GitHub (pinned to 79299dce87)