Mutable objects can lead to situation wherein it can be put into a hash but never retrieved from it (or rather even worse something else gets returned)...

Even though it is evident in most cases, but its not so evident all the time especially when we have deep hashcode dependencies. Consider the following

class Person
{
    public Person(string name, Person parent)
    {
        this.name = name;
        this.parent = parent;
    }

    public string name;
    public Person parent;

    public override int GetHashCode()
    {
        int hashCode = name.GetHashCode();
        if (parent != null)
            hashCode ^= parent.GetHashCode();

        return hashCode;
    }
}

static void Main(string[] args)
{
    Dictionary hash = new Dictionary();

    Person parent = new Person("Beeblebox", null);
    Person zaphod = new Person("Zaphod", parent);

    hash.Add(zaphod, zaphod);
    parent.name = "SomethingElse";

    Console.WriteLine(hash.ContainsKey(zaphod)); // Will print false
}

Here Person is mutable on different levels. Its directly mutable and also deep-mutable as it contains a reference to parent (which in turn is mutable).

Additionally, Person's hashcode depends on it's mutable fields. So in effect if any of the mutable references change then the next GetHashCode will return a different value and hence its lookup inside Dictionary will fail as Dictionary uses the hashcode of the objects place inside it.

Since in the example above the mutation of parent happens inline, it's easy to figure it out. However, it could well be in some obscure corner of the code base.