diff --git a/rigify/rigs/biped/arm/ik.py b/rigify/rigs/biped/arm/ik.py
index c341ede678222f3ee1f74c4d7145677c6895acb5..2b941b9e6cfb5cdc654de0fb56bf43ed9e3ef4ed 100644
--- a/rigify/rigs/biped/arm/ik.py
+++ b/rigify/rigs/biped/arm/ik.py
@@ -18,7 +18,7 @@
 
 import bpy
 from mathutils import Vector
-from math import pi
+from math import pi, acos
 from rigify.utils import MetarigError
 from rigify.utils import copy_bone
 from rigify.utils import connected_children_names
@@ -28,6 +28,33 @@ from rigify.utils import create_widget, create_line_widget, create_sphere_widget
 from rna_prop_ui import rna_idprop_ui_prop_get
 
 
+def angle_on_plane(plane, vec1, vec2):
+    """ Return the angle between two vectors projected onto a plane.
+    """
+    plane.normalize()
+    vec1 = vec1 - (plane * (vec1.dot(plane)))
+    vec2 = vec2 - (plane * (vec2.dot(plane)))
+    vec1.normalize()
+    vec2.normalize()
+
+    # Determine the angle
+    angle = acos(max(-1.0, min(1.0, vec1.dot(vec2))))
+
+    if angle < 0.00001:  # close enough to zero that sign doesn't matter
+        return angle
+
+    # Determine the sign of the angle
+    vec3 = vec2.cross(vec1)
+    vec3.normalize()
+    sign = vec3.dot(plane)
+    if sign >= 0:
+        sign = 1
+    else:
+        sign = -1
+
+    return angle * sign
+
+
 class Rig:
     """ An IK arm rig, with an optional ik/fk switch.
 
@@ -130,6 +157,12 @@ class Rig:
         vishand_e.tail = vishand_e.head + Vector((0, 0, v1.length / 32))
         vispole_e.tail = vispole_e.head + Vector((0, 0, v1.length / 32))
 
+        # Determine the pole offset value
+        plane = (farm_e.tail - uarm_e.head).normalize()
+        vec1 = uarm_e.x_axis.normalize()
+        vec2 = (pole_e.head - uarm_e.head).normalize()
+        pole_offset = angle_on_plane(plane, vec1, vec2)
+
         # Object mode, get pose bones
         bpy.ops.object.mode_set(mode='OBJECT')
         pb = self.obj.pose.bones
@@ -172,14 +205,7 @@ class Rig:
         con.subtarget = hand
         con.pole_target = self.obj
         con.pole_subtarget = pole
-        if self.primary_rotation_axis == 'X' or self.primary_rotation_axis == 'Y':
-            con.pole_angle = -pi / 2
-        elif self.primary_rotation_axis == '-X' or self.primary_rotation_axis == '-Y':
-            con.pole_angle = pi / 2
-        elif self.primary_rotation_axis == 'Z':
-            con.pole_angle = 0.0
-        elif self.primary_rotation_axis == '-Z':
-            con.pole_angle = pi
+        con.pole_angle = pole_offset
         con.chain_count = 2
 
         # Constrain org bones to controls
diff --git a/rigify/rigs/biped/leg/ik.py b/rigify/rigs/biped/leg/ik.py
index 5697a2b6446315b264484afc0fd053070f9f3e3b..a04b57dc5ec7c12ce9d0762fe4e664ec1acece39 100644
--- a/rigify/rigs/biped/leg/ik.py
+++ b/rigify/rigs/biped/leg/ik.py
@@ -36,12 +36,7 @@ def align_x_axis(obj, bone, vec):
     """
     vec.normalize()
     bone_e = obj.data.edit_bones[bone]
-    dot = bone_e.x_axis.dot(vec)
-    if dot < -1:
-        dot = -1
-    elif dot > 1:
-        dot = 1
-
+    dot = max(-1.0, min(1.0, bone_e.x_axis.dot(vec)))
     angle = acos(dot)
 
     bone_e.roll += angle
@@ -56,6 +51,33 @@ def align_x_axis(obj, bone, vec):
         bone_e.roll += angle * 2
 
 
+def angle_on_plane(plane, vec1, vec2):
+    """ Return the angle between two vectors projected onto a plane.
+    """
+    plane.normalize()
+    vec1 = vec1 - (plane * (vec1.dot(plane)))
+    vec2 = vec2 - (plane * (vec2.dot(plane)))
+    vec1.normalize()
+    vec2.normalize()
+
+    # Determine the angle
+    angle = acos(max(-1.0, min(1.0, vec1.dot(vec2))))
+
+    if angle < 0.00001:  # close enough to zero that sign doesn't matter
+        return angle
+
+    # Determine the sign of the angle
+    vec3 = vec2.cross(vec1)
+    vec3.normalize()
+    sign = vec3.dot(plane)
+    if sign >= 0:
+        sign = 1
+    else:
+        sign = -1
+
+    return angle * sign
+
+
 class Rig:
     """ An IK leg rig, with an optional ik/fk switch.
 
@@ -258,6 +280,12 @@ class Rig:
         foot_ik_target_e.head = Vector(org_foot_e.head)
         foot_ik_target_e.tail = Vector(org_foot_e.tail)
 
+        # Determine the pole offset value
+        plane = (shin_e.tail - thigh_e.head).normalize()
+        vec1 = thigh_e.x_axis.normalize()
+        vec2 = (pole_e.head - thigh_e.head).normalize()
+        pole_offset = angle_on_plane(plane, vec1, vec2)
+
         # Object mode, get pose bones
         bpy.ops.object.mode_set(mode='OBJECT')
         pb = self.obj.pose.bones
@@ -312,14 +340,7 @@ class Rig:
         con.subtarget = foot_ik_target
         con.pole_target = self.obj
         con.pole_subtarget = pole
-        if self.primary_rotation_axis == 'X' or self.primary_rotation_axis == 'Y':
-            con.pole_angle = -pi / 2
-        elif self.primary_rotation_axis == '-X' or self.primary_rotation_axis == '-Y':
-            con.pole_angle = pi / 2
-        elif self.primary_rotation_axis == 'Z':
-            con.pole_angle = 0.0
-        elif self.primary_rotation_axis == '-Z':
-            con.pole_angle = pi
+        con.pole_angle = pole_offset
         con.chain_count = 2
 
         # toe_parent constraint
diff --git a/rigify/rigs/finger.py b/rigify/rigs/finger.py
index de028f3606f82814a5df1ec4c3ce567d2f858492..f5788d023fb94679b6c0f35dfa7b91f902a11753 100644
--- a/rigify/rigs/finger.py
+++ b/rigify/rigs/finger.py
@@ -39,6 +39,10 @@ class Rig:
         self.org_bones = [bone] + connected_children_names(obj, bone)
         self.params = params
 
+        if len(self.org_bones) <= 1:
+            raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 2 or more bones." % (strip_org(bone)))
+
+
         # Get user-specified layers, if they exist
         if params.separate_extra_layers:
             self.ex_layers = list(params.extra_layers)