---
name: "keyctl_watch_key"
section: "3"
platform: "linux"
package: "keyutils"
version: "1.6.3-4"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/keyctl_watch_key"
---

# keyctl\_watch\_key(3)

Watch for changes to a key

## NAME

keyctl\_watch\_key - Watch for changes to a key

## SYNOPSIS

```
#include <keyutils.h>

long keyctl_watch_key(key_serial_t key,
                      int watch_queue_fd
                      int watch_id);
```

## DESCRIPTION

**keyctl\_watch\_key**() sets or removes a watch on *key*.

*watch\_id* specifies the ID for a watch that will be included in notification messages. It can be between 0 and 255 to add a key; it should be -1 to remove a key.

*watch\_queue\_fd* is a file descriptor attached to a watch\_queue device instance.  Multiple openings of a device provide separate instances.  Each device instance can only have one watch on any particular key.

### Notification Record

Key-specific notification messages that the kernel emits into the buffer have the following format:

```
struct key_notification {
	struct watch_notification watch;
	__u32	key_id;
	__u32	aux;
};
```

The *watch.type* field will be set to **WATCH\_TYPE\_KEY\_NOTIFY** and the *watch.subtype* field will contain one of the following constants, indicating the event that occurred and the watch\_id passed to keyctl\_watch\_key() will be placed in *watch.info* in the ID field.  The following events are defined:

- **NOTIFY\_KEY\_INSTANTIATED**

  This indicates that a watched key got instantiated or negatively instantiated. *key\_id* indicates the key that was instantiated and *aux* is unused.

- **NOTIFY\_KEY\_UPDATED**

  This indicates that a watched key got updated or instantiated by update. *key\_id* indicates the key that was updated and *aux* is unused.

- **NOTIFY\_KEY\_LINKED**

  This indicates that a key got linked into a watched keyring. *key\_id* indicates the keyring that was modified *aux* indicates the key that was added.

- **NOTIFY\_KEY\_UNLINKED**

  This indicates that a key got unlinked from a watched keyring. *key\_id* indicates the keyring that was modified *aux* indicates the key that was removed.

- **NOTIFY\_KEY\_CLEARED**

  This indicates that a watched keyring got cleared. *key\_id* indicates the keyring that was cleared and *aux* is unused.

- **NOTIFY\_KEY\_REVOKED**

  This indicates that a watched key got revoked. *key\_id* indicates the key that was revoked and *aux* is unused.

- **NOTIFY\_KEY\_INVALIDATED**

  This indicates that a watched key got invalidated. *key\_id* indicates the key that was invalidated and *aux* is unused.

- **NOTIFY\_KEY\_SETATTR**

  This indicates that a watched key had its attributes (owner, group, permissions, timeout) modified. *key\_id* indicates the key that was modified and *aux* is unused.

### Removal Notification

When a watched key is garbage collected, all of its watches are automatically destroyed and a notification is delivered to each watcher.  This will normally be an extended notification of the form:

```
struct watch_notification_removal {
	struct watch_notification watch;
	__u64	id;
};
```

The *watch.type* field will be set to **WATCH\_TYPE\_META** and the *watch.subtype* field will contain **WATCH\_META\_REMOVAL\_NOTIFICATION**. If the extended notification is given, then the length will be 2 units, otherwise it will be 1 and only the header will be present.

The watch\_id passed to *keyctl\_watch\_key*() will be placed in *watch.info* in the ID field.

If the extension is present, *id* will be set to the ID of the destroyed key.

## RETURN VALUE

On success **keyctl\_watch\_key**() returns **0 .** On error, the value **-1** will be returned and *errno* will have been set to an appropriate error.

## ERRORS

- **ENOKEY**

  The specified key does not exist.

- **EKEYEXPIRED**

  The specified key has expired.

- **EKEYREVOKED**

  The specified key has been revoked.

- **EACCES**

  The named key exists, but does not grant **view** permission to the calling process.

- **EBUSY**

  The specified key already has a watch on it for that device instance (add only).

- **EBADSLT**

  The specified key doesn't have a watch on it (removal only).

## LINKING

This is a library function that can be found in *libkeyutils*. When linking, **-lkeyutils** should be specified to the linker.

## SEE ALSO

[**keyctl**(1)](/keyctl/1.md), [**add\_key**(2)](/add_key/2.md), [**keyctl**(2)](/keyctl/2.md), [**request\_key**(2)](/request_key/2.md), [**keyctl**(3)](/keyctl/3.md), [**keyrings**(7)](/keyrings/7.md), [**keyutils**(7)](/keyutils/7.md)
