juicedata/juicefs · error

update table node: %s

Error message

update table node: %s

What it means

During legacy schema upgrade in doNewSession, after syncing added tables, JuiceFS syncs the node table (needed to add the primary key). A syncTable(new(node)) failure is wrapped as 'update table node: %s' and aborts the mount.

Source

Thrown at pkg/meta/sql.go:772

		s := setting{Name: "format"}
		ok, err := ses.Get(&s)
		if err == nil && ok {
			data = []byte(s.Value)
		}
		return err
	})
	return
}

func (m *dbMeta) doNewSession(sinfo []byte, update bool) error {
	// add new table
	err := m.syncTable(new(session2), new(delslices), new(dirStats), new(detachedNode), new(dirQuota), new(userGroupQuota), new(acl), new(delegationToken), new(changeLog))
	if err != nil {
		return fmt.Errorf("update table session2, delslices, dirstats, detachedNode, dirQuota, userGroupQuota, acl, changeLog: %s", err)
	}
	// add node table
	if err = m.syncTable(new(node)); err != nil {
		return fmt.Errorf("update table node: %s", err)
	}
	// add primary key
	if err = m.syncTable(new(edge), new(chunk), new(xattr), new(sustained)); err != nil {
		return fmt.Errorf("update table edge, chunk, xattr, sustained: %s", err)
	}
	// update the owner from uint64 to int64
	if err = m.syncTable(new(flock), new(plock)); err != nil {
		return fmt.Errorf("update table flock, plock: %s", err)
	}

	for {
		beans := session2{Sid: m.sid, Expire: m.expireTime(), Info: sinfo}
		if update {
			return m.txn(func(s *xorm.Session) error {
				_, err = s.Cols("expire", "info").Update(&beans, &session2{Sid: beans.Sid})
				if err == nil {
					m.genLog(Background(), s, time.Now().UnixNano(), "NEWSESSION(%d,%d,%s)", m.sid, beans.Expire, logEncode(sinfo))
				}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Check for duplicate Inode rows in the node table and deduplicate before the upgrade (juicefs fsck can help)
  2. Grant ALTER privilege to the metadata user
  3. Kill long-running transactions holding locks on the node table and retry the mount
  4. Back up the metadata before the schema upgrade

Example fix

-- before
ALTER TABLE jfs_node ADD PRIMARY KEY (inode); -- fails on duplicates
-- after
-- dedupe first, e.g. keep min(rowid) per inode, then re-run mount so syncTable adds the primary key
Defensive patterns

Strategy: validation

Validate before calling

-- Check for duplicate inodes blocking the primary key before upgrading
SELECT inode, COUNT(*) c FROM node GROUP BY inode HAVING c > 1;

Try / catch

if err := mount(sqlURL); err != nil {
    if strings.Contains(err.Error(), "update table node") {
        log.Fatalf("dedupe node.inode rows and retry: %v", err)
    }
}

Prevention

When it happens

Trigger: Mounting an old-format volume when altering the node table fails — e.g. duplicate rows preventing primary key creation, insufficient ALTER privilege, or lock timeout on a large node table.

Common situations: Upgrading a volume with duplicate inode rows in node (prevents adding primary key); RDS account without ALTER; long-running transaction holding metadata locks on node.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/f06106015135e3bf. Report an issue: GitHub.