apache/hadoop · error

mutexUnlock: pthread_mutex_unlock failed with error %d

Error message

mutexUnlock: pthread_mutex_unlock failed with error %d

What it means

mutexUnlock() wraps pthread_mutex_unlock and prints this when unlocking fails: EPERM (calling thread does not own the mutex) or EINVAL (mutex not initialized). Because the wrapper only logs and returns, the mutex remains locked — subsequent lockers deadlock, so this line usually precedes a hang.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/os/posix/mutexes.c:46

__attribute__((constructor)) static void init() {
  pthread_mutexattr_init(&jvmMutexAttr);
  pthread_mutexattr_settype(&jvmMutexAttr, PTHREAD_MUTEX_RECURSIVE);
  pthread_mutex_init(&jvmMutex, &jvmMutexAttr);
}

int mutexLock(mutex *m) {
  int ret = pthread_mutex_lock(m);
  if (ret) {
    fprintf(stderr, "mutexLock: pthread_mutex_lock failed with error %d\n",
      ret);
  }
  return ret;
}

int mutexUnlock(mutex *m) {
  int ret = pthread_mutex_unlock(m);
  if (ret) {
    fprintf(stderr, "mutexUnlock: pthread_mutex_unlock failed with error %d\n",
      ret);
  }
  return ret;
}

View on GitHub (pinned to 2add963021)

Solutions

  1. Map the code: EPERM — find the real owner with gdb (thread apply all bt) and make lock/unlock happen on the same thread
  2. Audit every early-return path between the matching mutexLock and this unlock for missing or duplicate unlocks
  3. If EINVAL, check for double init/destroy of the mutex and run ASan for overruns near it
  4. After fixing, verify under load that no follow-on deadlock remains (the lock was left held)

Example fix

/* before: multiple returns, unlock paths diverge */
mutexLock(&m);
if (err) return;      /* lock leaked */
do_work();
mutexUnlock(&m);

/* after: single exit guarantees pairing */
mutexLock(&m);
if (!err) do_work();
mutexUnlock(&m);
Defensive patterns

Strategy: validation

Try / catch

/* single exit point keeps lock/unlock paired */
mutexLock(&m);
ret = do_work();
mutexUnlock(&m);
return ret;

Prevention

When it happens

Trigger: Unlocking jvmMutex or jclassInitMutex from a thread other than the one that locked it; unlocking after the storage was reinitialized (EINVAL); error paths that reach an extra unlock.

Common situations: Hand-off designs where thread A locks and thread B unlocks; cleanup code that unlocks on a path where the lock was already released; corruption of static mutex storage.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/a7d0f4ab8f32be20. Report an issue: GitHub.