Consider the below. Is sizeof(_ht_entry) correct? To check, I needed to search for the type of table (some wheresomewhere at the start of the function) , find ht, search for ht definition (itsit is in another file).
Easy to code right, review and maintain. No need to look up table, notnor _entries definition.
(OP does not use _ht_create(0) yet, but ...)
Below tests for out-of-memory by table->_entries == NULL, yet a NULL is an acceptable return value when table->_capacity == 0. (C17 somewhat addresses this, but not enough).
Rather than rollmix the result of the get() with a reserved pointer value, separate the error flag from data. The data should be allowed to be anything.
// size_t ht_length(ht* table);
size_t ht_length(const ht* table);
Initialize all of the iterator
hti ht_iterator(ht* table) {
//hti it;
//it._table = table;
//it._index = 0;
hti it = { ._table = table, ._index = 0 }; // other members become 0
return it;
}