kataras/iris · error

malformed document file:

Error message

malformed document file: 

What it means

After decoding, AllowUsersFile expects the document to be either a username->password map or a list of objects each containing username/password fields. If neither decoded structure has entries, it panics with 'malformed document file'. The file parsed successfully but its shape does not match any supported form.

Source

Thrown at middleware/basicauth/user.go:199

	}

	if len(usernamePassword) > 0 {
		// JSON Form: { "$username":"$pass", "$username": "$pass" }
		// YAML Form: $username: $pass
		// 			  $username: $pass
		return userMap(usernamePassword, opts...)
	}

	if len(userList) > 0 {
		// JSON Form: [{"username": "$username", "password": "$pass", "other_field": ...}, {"username": ...}, ... ]
		// YAML Form:
		// - username: $username
		//   password: $password
		//   other_field: ...
		return AllowUsers(userList, opts...)
	}

	panic("malformed document file: " + jsonOrYamlFilename)
}

func decodeFile(src string, dest ...any) error {
	data, err := ReadFile(src)
	if err != nil {
		return err
	}

	// We use unmarshal instead of file decoder
	// as we may need to read it more than once (dests, see below).
	var (
		unmarshal func(data []byte, v any) error
		ext       string
	)

	if idx := strings.LastIndexByte(src, '.'); idx > 0 {
		ext = src[idx:]
	}

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Reshape the file to {"username":"password", ...} or a YAML list of {username: ..., password: ...} entries.
  2. Ensure every entry has keys extractable as username and password (check exact key names and casing).
  3. If fields differ, decode the file yourself into structs with Username/Password fields and pass the slice to AllowUsers instead.

Example fix

// before (users.yml)
accounts:
  - name: admin
    secret: pass
// after (users.yml)
- username: admin
  password: pass
Defensive patterns

Strategy: validation

Validate before calling

var check struct {
    Users []map[string]any `yaml:"users" json:"users"`
}
data, _ := os.ReadFile(path)
if err := yaml.Unmarshal(data, &check); err != nil || len(check.Users) == 0 {
    // also try flat map form before failing
    var m map[string]string
    if err2 := yaml.Unmarshal(data, &m); err2 != nil || len(m) == 0 {
        return errors.New("users file has no recognizable username/password entries")
    }
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        log.Fatalf("basicauth users file malformed: %v", r)
    }
}()
h := basicauth.Load("users.yml")

Prevention

When it happens

Trigger: Loading a users file whose top level is a JSON array of strings, a YAML document with neither map nor list form, or whose entries lack usable username/password keys (all entries skipped by extractUsernameAndPassword), or an empty file.

Common situations: Hand-edited YAML where fields were renamed (user/name instead of username/password); a file that only holds bcrypt hashes without usernames; an empty placeholder file committed to the repo.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/8f5b9850b426990b. Report an issue: GitHub.